3

I use RUST_BACKTRACE=full ./my-program to run my compiled program. However, I get a message like below which has only the function address without line numbers.

thread 'main' panicked at 'index out of bounds: the len is 6 but the index is 6', src/libcore/slice/mod.rs:734
stack backtrace:
   0:        0x100a26463 - std::sys::imp::backtrace::tracing::imp::unwind_backtrace::hbdeac7eba2f064c6
   1:        0x100a2786d - std::panicking::default_hook::{{closure}}::h9e0a6ca9bb64b479
   2:        0x100a27434 - std::panicking::default_hook::h9043ae80af471c9f
   3:        0x100a29f17 - std::panicking::rust_panic_with_hook::h05996066754c6be9
   4:        0x100a29e04 - std::panicking::begin_panic::h9fecf34da42eb910
   5:        0x100a29d22 - std::panicking::begin_panic_fmt::he5aad713258a67c3
   6:        0x100a29c87 - rust_begin_unwind
   7:        0x100a4a5f0 - core::panicking::panic_fmt::he26d734b771c5b2c
   8:        0x100a4a568 - core::panicking::panic_bounds_check::h19dd3f615b4fea05
   9:        0x100a1fc76 - <usize as core::slice::SliceIndex<[T]>>::index::h1f41340feec36937
  10:        0x100a1f744 - core::slice::<impl core::ops::Index<I> for [T]>::index::h3246d2321fb7f789
  11:        0x100a205b6 - sort::merge::h697218a53d5049aa
  12:        0x100a20227 - sort::merge_sort::h10fe012581f48b43
  13:        0x100a201e5 - sort::merge_sort::h10fe012581f48b43
  14:        0x100a201e5 - sort::merge_sort::h10fe012581f48b43
  15:        0x100a20159 - sort::merge_sort_pub::hb18b616b61510f3b
  16:        0x100a20e24 - sort::main::hffac78b51f3ea2c3
  17:        0x100a29c45 - std::panicking::try::do_call::h24a2756282b9a31c
  18:        0x100a2ba2a - __rust_maybe_catch_panic
  19:        0x100a2a1d0 - std::rt::lang_start::hd19f94db0c6a490e
  20:        0x100a20fc9 - main

Is there any method to add the line numbers at the break spot?

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
wind2412
  • 1,011
  • 1
  • 9
  • 24
  • Compile with debug information. Perhaps [libbacktrace](https://github.com/ianlancetaylor/libbacktrace) has been ported or interfaced to Rust. – Basile Starynkevitch Apr 09 '17 at 05:46
  • 2
    I'm not sure but you might be able to get more information using `rust-gdb`. Make sure to compile with the `-g` flag. – Kent Shikama Apr 09 '17 at 05:46
  • @MatthieuM. In fact, as the [issue](https://github.com/rust-lang/rust/issues/24346#issuecomment-22137581%E2%80%8C%E2%80%8B0) said that... seems like linux has this same issue as well. But whatever:) – wind2412 Apr 09 '17 at 14:27
  • @wind2412: In my (oldish) Ubuntu VM I have the file and line displayed. – Matthieu M. Apr 09 '17 at 14:31
  • @MatthieuM. Actually on my docker this work well, too. That's okay.:) – wind2412 Apr 09 '17 at 14:33

1 Answers1

4

This problem is a cross-platform issue and is tracked as Rust issue 24346. My workspace is macOS 10.12.4:

>rustc -vV
rustc 1.18.0-nightly (2564711e8 2017-04-04)
binary: rustc
commit-hash: 2564711e803f62e04bebf10408cc1c11297c0caf
commit-date: 2017-04-04
host: x86_64-apple-darwin
release: 1.18.0-nightly
LLVM version: 3.9

The workaround is to use a debugger to get the callstack information.

I have a hellobugs.rs file only present several lines of buggy code. At line 3, I cause a panic due to accessing the vector out of bounds:

fn main() {                // 1
    let v = vec![1, 2, 3]; // 2
    println!("{}", v[4]);  // 3
}                          // 4

Compile this with rustc hellobugs.rs -g -o hellobugs Don't forget the -g argument.

Running with RUST_BACKTRACE=full ./hellobugs will get backtraces but without line numbers on my macOS. As the issue says, we can use rust-lldb hellobugs to debug it and get detailed backtraces. Of course, using lldb is okay as well:

>rust-lldb hellobugs
    ...lots of rust-lldb message...
(lldb) breakpoint set -b rust_begin_unwind
Breakpoint 1: where = hellobugs`std::panicking::rust_begin_panic + 4 at panicking.rs:468, address = 0x000000010000a5b4
(lldb) r
Process 41626 launched: '/Users/xxx/bin/hellobugs' (x86_64)
hellobugs was compiled with optimization - stepping may behave oddly; variables may not be available.
Process 41626 stopped
* thread #1: tid = 0x6c3e39, 0x000000010000a5b4 hellobugs`std::panicking::rust_begin_panic + 4 at panicking.rs:468, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x000000010000a5b4 hellobugs`std::panicking::rust_begin_panic + 4 at panicking.rs:468 [opt]
(lldb) bt
* thread #1: tid = 0x6c3e39, 0x000000010000a5b4 hellobugs`std::panicking::rust_begin_panic + 4 at panicking.rs:468, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x000000010000a5b4 hellobugs`std::panicking::rust_begin_panic + 4 at panicking.rs:468 [opt]
    frame #1: 0x000000010002af51 hellobugs`core::panicking::panic_fmt + 129 at panicking.rs:69 [opt]
    frame #2: 0x000000010002aec9 hellobugs`core::panicking::panic_bounds_check + 105 at panicking.rs:56 [opt]
    frame #3: 0x0000000100001726 hellobugs`collections::vec::{{impl}}::index<i32>(self=0x00007fff5fbff720, index=4) + 118 at vec.rs:1426
    frame #4: 0x0000000100001826 hellobugs`hellobugs::main + 182 at hellobugs.rs:3
    frame #5: 0x000000010000a5a6 hellobugs`std::panicking::try::do_call<fn(),()> [inlined] core::ops::FnOnce::call_once<fn(),()> + 6 at ops.rs:2606 [opt]
    frame #6: 0x000000010000a5a4 hellobugs`std::panicking::try::do_call<fn(),()> + 4 at panicking.rs:454 [opt]
    frame #7: 0x000000010000c38b hellobugs`panic_unwind::__rust_maybe_catch_panic + 27 at lib.rs:98 [opt]
    frame #8: 0x000000010000ab31 hellobugs`std::rt::lang_start [inlined] std::panicking::try<(),fn()> + 44 at panicking.rs:433 [opt]
    frame #9: 0x000000010000ab05 hellobugs`std::rt::lang_start [inlined] std::panic::catch_unwind<fn(),()> at panic.rs:361 [opt]
    frame #10: 0x000000010000ab05 hellobugs`std::rt::lang_start + 325 at rt.rs:57 [opt]
    frame #11: 0x000000010000192a hellobugs`main + 42
    frame #12: 0x00007fffdfc5f235 libdyld.dylib`start + 1
(lldb)

My results are as above. You can see at frame #4 there comes the buggy result of at hellobug.rs:3. This informs us the 3rd line has a bug. It is a little bother to use lldb and trace, but it's accurate!

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
wind2412
  • 1,011
  • 1
  • 9
  • 24
  • Does lldb has anything like gdb's `catch throw` (which catch any exception being thrown)? It could be easier than to set the breakpoint as you do. – Matthieu M. Apr 09 '17 at 14:06
  • @MatthieuM. [there's this](http://stackoverflow.com/q/8122375/155423), but I'm not sure if a panic counts as an exception from the perspective of the debugger. Does `catch throw` work for Rust code? – Shepmaster Apr 09 '17 at 14:18
  • FWIW, I break on `rust_panic` - it's a few keys less, if nothing else ;-) – Shepmaster Apr 09 '17 at 14:19
  • @MatthieuM. I don't know about this~ I used gdb before. However my workspace can't use gdb to debug Rust code. The [issue](https://github.com/rust-lang/rust/issues/40787) is also open yet... sad – wind2412 Apr 09 '17 at 14:31
  • 1
    @Shepmaster: I tried with gdb 7.7, and `catch throw` didn't work. Too much C++ of late I guess. Would be sweet though... – Matthieu M. Apr 09 '17 at 14:31