Skip to content
This repository was archived by the owner on May 21, 2019. It is now read-only.

Expression evaluation for rust #20

Open
fedochet opened this issue Oct 22, 2018 · 18 comments
Open

Expression evaluation for rust #20

fedochet opened this issue Oct 22, 2018 · 18 comments

Comments

@fedochet
Copy link

Hi! I'd like to ask about the status of expression evaluation in rust-lldb
From what I've experienced it supports only a small amount of features (like calling regular functions or methods of the primary structure impls, but not methods from traits for example, and not methods from data structures like Vec)
Are there plans for adding support for such functionality?

@tromey
Copy link
Collaborator

tromey commented Oct 23, 2018

but not methods from traits for example

I'm planning to do this, but it requires rust-lang/rust#33014, which in turn requires an LLVM patch (I have the start of this, but not enough to submit).

not methods from data structures like Vec

Could you expand on what you mean by this?

Another missing function-call-related bit is calling methods on trait objects. That requires the second half of rust-lang/rust#1563

@fedochet
Copy link
Author

fedochet commented Oct 23, 2018

Could you expand on what you mean by this?

For example, if I have code like this:

let mut v = vec![1,2,3]; 
v.push(4); // breakpoint is set here
println!("{}", v[3]);

I've tried to call v.push(42) between the first and the second line, but with no luck
As I understand it, it cannot be done because of heavy inlining of vector methods. Is it right, or it has to do with something else?

@tromey
Copy link
Collaborator

tromey commented Oct 25, 2018

As I understand it, it cannot be done because of heavy inlining of vector methods. Is it right, or it has to do with something else?

Yes, that's the problem in this case. One possible way to fix this would be to reimplement expression evaluation using miri, but that is a difficult project.

@fedochet
Copy link
Author

to reimplement expression evaluation using miri

You mean to do that inside of the rust-lldb, or as a separate project?

@tromey
Copy link
Collaborator

tromey commented Oct 25, 2018

Inside the rust-enabled lldb; but really preferably as some kind of library so we can do the same in gdb.

@fedochet
Copy link
Author

Can you please provide some more details about what steps are need to be taken in order to implement expression evaluation using miri?
You will have to learn how to compile single rust expression into miri, and then add support to lldb to invoke miri expressions? Or am I misunderstanding something?

@tromey
Copy link
Collaborator

tromey commented Oct 25, 2018

I don't really know anything about miri; I"m afraid this investigation is one of the bigger parts of the task.

@fedochet
Copy link
Author

Okay. Can I ask you about how rust expressions currently are "interpreted" in lldb? Are they compiled to something, or are they parsed and executed in terms of C-calls?

@tromey
Copy link
Collaborator

tromey commented Oct 25, 2018

Currently there is a parser and evaluator here: https://github.com/rust-lang-nursery/lldb/tree/rust-release-80-v1/source/Plugins/ExpressionParser/Rust. They aren't compiled, there is also a simple interpreter in there.

Most of this would be replaced in the miri plan, but there would still need to be an lldb bridge to access local variables and memory, at the very least.

@jeremysalwen
Copy link

What exactly is the status of expression evaluation in rust-lldb and rust-gdb distributed with nightly?

rust-lldb doesn't even seem to try to evaluate functions:

print (**curr_node).get_pointer(0)
error: no field named get_pointer

rust-gdb seems to be unable to find methods declared directly on a struct:

Could not find function named 'extended_collections::skiplist::tsplist::Node<u32>::get_pointer' (from interpreter-exec --thread 160 --frame 0 console "print (**curr_node).get_pointer(0)")
Could not find function named 'extended_collections::skiplist::tsplist::Node<u32>::get_pointer'

I've tried to understand what I can evaluate from reading the different github threads, but it's still not clear to me what exactly is expected to work right now, and what is the syntax to use it.

@tromey
Copy link
Collaborator

tromey commented Jan 8, 2019

Function calls should work fine, and I'd expect an impl Struct function to be callable. What does not work is anything relying on traits, because traits are not exposed in the DWARF.

The best thing to do in cases where it fails is to try to write a small reproducer and then file a separate bug.

I see I didn't write any tests for calls via impl Struct. So maybe I forgot to implement that. I will look into it. (For gdb, though, there are definitely tests for this, so if it isn't working in gdb then that is some new bug.)

@jeremysalwen
Copy link

Where should I file bugs? Here is an example, with the latest nightly: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6193616cd6aa584793bcb730269a6eac

Both rust-gdb and rust-lldb fail

$ rust-lldb target/debug/deps/exampledgb-0f6ba88c6ac57fe3
(lldb) command script import "/home/jeremysalwen/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/etc/lldb_rust_formatters.py"
(lldb) type summary add --no-value --python-function lldb_rust_formatters.print_val -x ".*" --category Rust
(lldb) type category enable Rust
(lldb) target create "target/debug/deps/exampledgb-0f6ba88c6ac57fe3"
Current executable set to 'target/debug/deps/exampledgb-0f6ba88c6ac57fe3' (x86_64).
(lldb) b main.rs:20
Breakpoint 1: where = exampledgb-0f6ba88c6ac57fe3`exampledgb::test_foo::h6982aa095a01d5c4 + 72 at main.rs:20, address = 0x0000000000011a28
(lldb) run
Process 196886 launched: '/home/jeremysalwen/fun/exampledgb/target/debug/deps/exampledgb-0f6ba88c6ac57fe3' (x86_64)

running 1 test
Process 196886 stopped
* thread #2, name = 'test_foo', stop reason = breakpoint 1.1
    frame #0: exampledgb-0f6ba88c6ac57fe3`exampledgb::test_foo::h6982aa095a01d5c4 at main.rs:20
   17  	fn test_foo() {
   18  	    println!("Hello test");
   19  	    let _foo = Foo {x: 5};
-> 20  	    panic!();
   21  	}
(lldb) p _foo.print()
error: no member named 'print' in 'exampledgb::Foo'
(lldb) 

$ rust-gdb target/debug/deps/exampledgb-0f6ba88c6ac57fe3
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from target/debug/deps/exampledgb-0f6ba88c6ac57fe3...done.
(gdb) b 20
Breakpoint 1 at 0x11a28: file src/main.rs, line 20.
(gdb) run
Starting program: /home/jeremysalwen/fun/exampledgb/target/debug/deps/exampledgb-0f6ba88c6ac57fe3 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

running 1 test
[New Thread 0x7ffff69ff700 (LWP 196987)]
[Switching to Thread 0x7ffff69ff700 (LWP 196987)]

Thread 2 "test_foo" hit Breakpoint 1, exampledgb::test_foo::h6982aa095a01d5c4 () at src/main.rs:20
20	    panic!();
(gdb) p _foo.print()
Could not find function named 'exampledgb::Foo::print'
(gdb) 

@tromey
Copy link
Collaborator

tromey commented Jan 9, 2019

Where should I file bugs?

lldb bugs can be filed here. The best place for gdb bugs is gdb bugzilla.

@tromey
Copy link
Collaborator

tromey commented Jan 9, 2019

Both rust-gdb and rust-lldb fail

gdb 8 works for me, but not gdb 7.12 (which is what you have). I don't recall offhand what bug this was, but I guess this was fixed already.

I still haven't looked into the lldb situation.

@jeremysalwen
Copy link

I upgraded to gdb 8.2, still getting the same behavior:

$ rust-gdb target/debug/deps/exampledgb-0f6ba88c6ac57fe3
GNU gdb (GDB) 8.2-gg5
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-grtev4-linux-gnu".
Type "show configuration" for configuration details.

<http://go/gdb-home FAQ: http://go/gdb-faq Email: c-toolchain-team>
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
Reading symbols from target/debug/deps/exampledgb-0f6ba88c6ac57fe3...done.
Unable to determine compiler version.
Skipping loading of libstdc++ pretty-printers for now.
Non-google3 binary detected.
(gdb) b rust_panic
Breakpoint 1 at 0x645c3: file libstd/panicking.rs, line 525.
(gdb) r
Starting program: /home/jeremysalwen/fun/exampledgb/target/debug/deps/exampledgb-0f6ba88c6ac57fe3 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

running 1 test
[New Thread 0x7ffff69ff700 (LWP 70751)]
[Switching to Thread 0x7ffff69ff700 (LWP 70751)]

Thread 2 "test_foo" hit Breakpoint 1, rust_panic () at libstd/panicking.rs:525
525	libstd/panicking.rs: No such file or directory.
(gdb) bt
#0  rust_panic () at libstd/panicking.rs:525
#1  0x00005555555b85a9 in std::panicking::rust_panic_with_hook () at libstd/panicking.rs:496
#2  0x0000555555565c04 in std::panicking::begin_panic (msg="explicit panic", file_line_col=0x555555822008) at libstd/panicking.rs:410
#3  0x0000555555565a40 in exampledgb::test_foo () at src/main.rs:20
#4  0x0000555555565b4a in exampledgb::test_foo::{{closure}} () at src/main.rs:17
#5  0x0000555555564cbe in core::ops::function::FnOnce::call_once () at libcore/ops/function.rs:238
#6  0x0000555555567f0f in test::run_test::{{closure}} () at libtest/lib.rs:1468
#7  core::ops::function::FnOnce::call_once () at libcore/ops/function.rs:238
#8  <F as alloc::boxed::FnBox<A>>::call_box () at liballoc/boxed.rs:672
#9  0x00005555555c80ea in __rust_maybe_catch_panic () at libpanic_unwind/lib.rs:102
#10 0x0000555555589b83 in std::panicking::try () at libstd/panicking.rs:289
#11 std::panic::catch_unwind () at libstd/panic.rs:392
#12 test::run_test::run_test_inner::{{closure}} () at libtest/lib.rs:1423
#13 std::sys_common::backtrace::__rust_begin_short_backtrace () at libstd/sys_common/backtrace.rs:136
#14 0x000055555558a5c5 in std::thread::Builder::spawn::{{closure}}::{{closure}} () at libstd/thread/mod.rs:409
#15 <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once () at libstd/panic.rs:313
#16 std::panicking::try::do_call () at libstd/panicking.rs:310
#17 0x00005555555c80ea in __rust_maybe_catch_panic () at libpanic_unwind/lib.rs:102
#18 0x000055555557784d in std::panicking::try () at libstd/panicking.rs:289
#19 std::panic::catch_unwind () at libstd/panic.rs:392
#20 std::thread::Builder::spawn::{{closure}} () at libstd/thread/mod.rs:408
#21 <F as alloc::boxed::FnBox<A>>::call_box () at liballoc/boxed.rs:672
#22 0x00005555555b5d1e in _$LT$alloc..boxed..Box$LT$$LP$dyn$u20$alloc..boxed..FnBox$LT$A$C$$u20$Output$u3d$R$GT$$u20$$u2b$$u20$$u27$a$RP$$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$::call_once::h9d902c911a417e39 () at liballoc/boxed.rs:682
#23 std::sys_common::thread::start_thread () at libstd/sys_common/thread.rs:24
#24 0x00005555555ab506 in std::sys::unix::thread::Thread::new::thread_start () at libstd/sys/unix/thread.rs:90
#25 0x00007ffff77b7494 in start_thread (arg=0x7ffff69ff700) at pthread_create.c:333
#26 0x00007ffff72e1a8f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:97
(gdb) frame 3
#3  0x0000555555565a40 in exampledgb::test_foo () at src/main.rs:20
20	    panic!();
(gdb) p _foo.print()
Could not find function named 'exampledgb::Foo::print'
(gdb) 

@tromey
Copy link
Collaborator

tromey commented Jan 18, 2019

I upgraded to gdb 8.2, still getting the same behavior:

The problem here is that when compiling with --test, nothing calls the print function, so it is omitted from the executable.

@jeremysalwen
Copy link

Is there a debug compilation option so that all functions are emitted?

@tromey
Copy link
Collaborator

tromey commented Jan 18, 2019

Is there a debug compilation option so that all functions are emitted?

Sorry, I don't know.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants