rustのgdbでのdebugでsourceを出力したかった
プログラム言語処理系のslackの#rustでKeenさんという方に色々教わってうまいこと動いたので書き残しておきます。
cargo buildをすると謎のdebug情報が付加される
/rustc/412f43ac5b4ae8c3599e71c6972112e9be4758fa
といったパスが情報に付加される
cargo build nm -l target/debug/hello | grep /rustc
000000000000d5d0 T __rust_maybe_catch_panic /rustc/412f43ac5b4ae8c3599e71c6972112e9be4758fa//src/libpanic_unwind/lib.rs:75 000000000000d660 T __rust_start_panic /rustc/412f43ac5b4ae8c3599e71c6972112e9be4758fa//src/libpanic_unwind/lib.rs:95 000000000000be20 T rust_begin_unwind /rustc/412f43ac5b4ae8c3599e71c6972112e9be4758fa//src/libstd/panicking.rs:301 000000000000d790 T rust_eh_personality /rustc/412f43ac5b4ae8c3599e71c6972112e9be4758fa//src/libpanic_unwind/gcc.rs:288 000000000000b640 T rust_oom /rustc/412f43ac5b4ae8c3599e71c6972112e9be4758fa//src/libstd/alloc.rs:209
gdbにはset substitute-pathという実行時に変更出来る設定があるのでそれを利用するとsできる
- gdbよく知らないけど簡単にshellかいてみる
#!/bin/sh TARGET_PATH=$1 DEBUG_SRC=`strings $TARGET_PATH | grep -o '^/rustc/[^/]\+/' | uniq` TMPGDBINIT=`mktemp -d` echo "set substitute-path $DEBUG_SRC $HOME/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/" >> $TMPDIR/.gdbinit rust-gdb -x $TMPDIR/.gdbinit $TARGET_PATH
(gdb) l 1 fn main() { 2 println!("Hello, world!"); 3 } (gdb) b 2 Breakpoint 1 at 0x3f70: file src/main.rs, line 2. (gdb) run Starting program: /data/target/debug/hello [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Breakpoint 1, hello::main () at src/main.rs:2 2 println!("Hello, world!"); (gdb) s core::fmt::Arguments::new_v1 (pieces=&[&str](len: 1) = {...}, args=&[core::fmt::ArgumentV1](len: 0)) at /rustc/412f43ac5b4ae8c3599e71c6972112e9be4758fa/src/libcore/fmt/mod.rs:319 319 args, (gdb) l 314 pub fn new_v1(pieces: &'a [&'a str], 315 args: &'a [ArgumentV1<'a>]) -> Arguments<'a> { 316 Arguments { 317 pieces, 318 fmt: None, 319 args, 320 } 321 } 322 323 /// This function is used to specify nonstandard formatting parameters.