Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rust-lldb: add a pretty printer for &mut slices #30232

Closed
zummenix opened this issue Dec 6, 2015 · 17 comments
Closed

rust-lldb: add a pretty printer for &mut slices #30232

zummenix opened this issue Dec 6, 2015 · 17 comments
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.

Comments

@zummenix
Copy link

zummenix commented Dec 6, 2015

Pretty printer for &mut slices doesn't work.

I tried this code:

fn main() {
    let mut v = vec![4, 6, 7, 8, 5, 1, 2, 3];
    slice_mut(&mut v);
}

fn slice_mut(a: &mut [u32]) {
}

In rust-lldb p a should print:

(&mut [u32]) $0 = &[4, 6, 7, 8, 5, 1, 2, 3]

Instead, it prints:

(&mut [u32]) $0 = &mut [u32] {
data_ptr: &0x10102b000, 
length: 8
}

Meta

rustc --version --verbose:

rustc 1.6.0-nightly (a2866e387 2015-11-30)
binary: rustc
commit-hash: a2866e387eab59528466a040e815568e57b20850
commit-date: 2015-11-30
host: x86_64-apple-darwin
release: 1.6.0-nightly
@zummenix
Copy link
Author

zummenix commented Dec 6, 2015

Seems like it should be easy to fix:

if (unqualified_type_name.startswith("&[") and
unqualified_type_name.endswith("]") and
self.__conforms_to_field_layout(SLICE_FIELD_NAMES)):
return TYPE_KIND_SLICE

@jdm jdm added E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) labels Dec 6, 2015
untitaker added a commit to untitaker/rust that referenced this issue Jan 15, 2016
@archshift
Copy link
Contributor

Is this still an issue?

@jdm
Copy link
Contributor

jdm commented Apr 19, 2016

Yes; #30249 was closed without merging the changes.

@nikhilshagri
Copy link
Contributor

nikhilshagri commented Jun 25, 2016

Does this issue appear for gdb as well? If yes, then I can try to fix it, since I have a linux machine.

EDIT: I looked at the closed PR, and noticed that a test was failing on a Mac. Hmm....so maybe this one isn't for me then:expressionless:

@Manishearth
Copy link
Member

@cynicaldevil actually, this failure is due to an issue in the common code (debugger_pretty_printers_common.py), where it classifies things as TYPE_CODE_SLICE. So the bug should appear in gdb as well.

I'm right now using gdb on a mac in an esoteric setup so I haven't gotten rust-gdb working again and can't verify, but you can try it out and try to fix it :)

@Manishearth
Copy link
Member

@tromey What is your opinion on slice pretty-printing? Right now in gdb we don't pretty-print slices much, but we could. However, without indexing support hiding the data pointer can be counterproductive in case it is a slice of complicated structs. The same goes for Vec and String -- should we encode knowledge of the internals in GDB itself and handle both pretty printing and indexing? Or leave pretty printing up to Rust's pretty printers? Right now in general there is significant overlap between what rust-gdb does and what trunk gdb does; I'm wondering if the goal is to eliminate rust-gdb pretty printing entirely; and perhaps package convenience functions like $unwrap()

@Manishearth Manishearth added the E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. label Jun 28, 2016
@Manishearth
Copy link
Member

(Willing to help anyone who wants to work on this)

@nikhilshagri
Copy link
Contributor

@Manishearth oh that's good. I am willing to try my hand at this then.

@Manishearth
Copy link
Member

First check that this is indeed a bug in gdb; I haven't yet checked locally 😄 . I'm just guessing by looking at the code.

@nikhilshagri
Copy link
Contributor

nikhilshagri commented Jun 28, 2016

I confirmed that the bug is present in gdb as well, here's the output:

(gdb) print a
$1 = {data_ptr = 0x7ffff6829060, length = 8}

Also, the pretty-print output of vector v in the main function appears like this:

(gdb) print v
$2 = {buf = {ptr = {pointer = {__0 = 0x7ffff6829060}, 
_marker = {<No data fields>}}, cap = 8}, len = 8}

Doesn't seem like this is the desired output. Also, I noticed that the lldb output mentions &mut [u32] as the data type of the variable, whereas no such thing shows up in gdb.

@Manishearth
Copy link
Member

Does it pretty-print an &[T] when using rust-gdb? Remember, you need to use rust-gdb (part of your rust install), not gdb.

@Manishearth
Copy link
Member

Make sure you set language rust in gdb too. Depending on the version of your compiler it might not detect it automatically.

(GDB trunk does print the type name, btw)

@nikhilshagri
Copy link
Contributor

damn, I used the normal gdb. I read some 'debugging rust' tutorials and they didn't mention anything about this. I will try it out using the rustc version then.

@Manishearth
Copy link
Member

(btw, feel free to ping me on #rust-tools (or any other Rust IRC channel) for a more realtime discussion)

@tromey
Copy link
Contributor

tromey commented Jun 28, 2016

@tromey What is your opinion on slice pretty-printing? Right now in gdb we don't pretty-print slices much, but we could. However, without indexing support hiding the data pointer can be counterproductive in case it is a slice of complicated structs. The same goes for Vec and String -- should we encode knowledge of the internals in GDB itself and handle both pretty printing and indexing? Or leave pretty printing up to Rust's pretty printers? Right now in general there is significant overlap between what rust-gdb does and what trunk gdb does; I'm wondering if the goal is to eliminate rust-gdb pretty printing entirely; and perhaps package convenience functions like $unwrap()

My view has been that types that are part of the language should be handled directly by gdb, while types from a library should be handled by pretty-printers; with String being a border case which should maybe be part of gdb.

It wasn't clear to me how gdb ought to print slices, so I left that alone. It's easy to change this; if you can tell me what it should do, I can implement it. Slice indexing ought to work already.

So, given this approach, there's still a useful role for rust-gdb. However there are still some holes:

  • It would be nice not to need rust-gdb at all. However, this is a pain given static linking and trying to find stuff in the filesystem. Maybe the hook script could search $PATH for rustc or something along those lines.
  • Vec indexing doesn't work right now. There are two possible solutions to this:
    1. Change rustc to emit the needed trait information and then change gdb to implement various opcodes via trait lookup. This would be great, with the (possibly minor) drawback that these operations would be inferior calls.
    2. Add something akin to the xmethod support to gdb for Rust. Then rust-gdb could implement indexing.

@Manishearth
Copy link
Member

It wasn't clear to me how gdb ought to print slices, so I left that alone.

Just like an array, really, prefixed by & or &mut.

However, this is a pain given static linking and trying to find stuff in the filesystem. Maybe the hook script could search $PATH for rustc or something along those lines.

Not sure what you mean here? Why do we need to look for rustc?

There are two possible solutions to this:

Well, two more:

  • Hardcode how to find the ptr/len in gdb. Brittle, though I don't expect the layout of Vec and String to change.
  • Expose convenience functions in std which can be called by GDB and LLDB. These are not generic -- they take a raw pointer to a vector and give you its length and data pointer. This is slightly better than the trait information thing because that function will not disappear on monomorphization. For example, Rust already has index trait methods in the debuginfo, which you can call, but they won't exist if the code doesn't index directly.

It seems like logically Vec/String handling should go in rust-gdb, since rust-gdb evolves with the stdlib (unlike gdb, which evolves independently). I do not like having rust-gdb continue existing; but I guess having a tiny rust-gdb with handling for string/vec and $unwrap() is okay. The convenience function solution is an alternative to this that lets rust-gdb disappear.

My main concern was indexing, but if you think it's possible to expose enough info to gdb python for this to work, I guess that's okay too.

@Manishearth
Copy link
Member

We shouldn't close this, once #34550 lands we need a test for lldb too

bors added a commit that referenced this issue Jul 4, 2016
Added a pretty printer for &mut slices

Fixes #30232
I have added a test which checks for correctness in gdb, but I need some help to do the same for lldb.

r? @Manishearth
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.
Projects
None yet
Development

No branches or pull requests

6 participants