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 ...

+3


source to share


2 answers


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.

+2


source


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/



+1


source







All Articles