How do you track down the source of the error?
RUST_BACKTRACE=1
Very useful for panic attacks , but it does not greatly affect non-fatal errors.
For example, I have a code ending with
match res {
Ok(()) => (),
Err(_) =>
println_err!("{:?}", res),
}
Unfortunately, working in gdb
the default doesn't do much, as nothing exceptional happens. (The behavior of older C ++ where unhandled exceptions would be thrown abort()
and gdb
broken on SIGABORT
by default was pretty handy.)
Further, since it gdb
now supports reverse execution, I thought I could debug it by setting a line breakpoint println_err
and changing it until I find the source of the error.
(gdb) reverse-step
Target multi-thread does not support this command.
A quick search showed that I should do something like
(gdb) set libthread-db-search-path /etc/nonexistent
(gdb) start
but then i get
(gdb) reverse-step
Target child does not support this command.
Does this mean that reverse debugging is simply not supported in Rust? Or am I doing something wrong / suboptimal?
Is there a better solution than manually stepping through each function that posted the error (with try!()
) to see where it was generated from?
Edit: Using manual breakpoints and restarts, I got to the point where the function was returning, but GDB can't tell what the return value is:
(gdb) finish
Run till exit from #0 cafs::reader::Reader::read_rawblock (self=0x7fffffffd628, h=Sha256 = {...}) at src/reader.rs:90
0x00005555556a096b in cafs::reader::Reader::read_blockref_vec (self=0x7fffffffd628, r=Reader = {...}) at src/reader.rs:101
101 let raw = try!(self.read_rawblock(h));
Value returned is $3 = {union Result<collections::vec::Vec<u8>, std::io::error::Error> (struct Reader *, struct Sha256)} 0x0
(gdb)
So, maybe GDB won't be useful ...
source to share
Reverse debugging is not as easy as reverse-step
. You have to stop at some point before the crash and ask gdb record
. Then at some later point, you can cancel.
The built-in recorder is on the slow side. And it doesn't support multithreading. It's hard to recommend it outside of some small use cases.
If you are serious about doing reverse debugging for this problem, let me recommend rr-project . This is a much better way to approach this.
source to share
If you want to have stacktraces with Result<T, E>
, you can create a type that does this: http://phildawes.net/blog/2015/06/17/rust-stacktrace/
source to share