Locating source of IO error in my code

when I run my tests with RUST_BACKTRACE=1 (or =full), I get this output:

Error: Aggregate signature error: IO error: No such file or directory (os error 2)

Caused by:
    0: IO error: No such file or directory (os error 2)
    1: No such file or directory (os error 2)

Stack backtrace:
   0: anyhow::error::<impl core::convert::From<E> for anyhow::Error>::from
             at /home/dotdev/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/anyhow-1.0.99/src/backtrace.rs:27:14
   1: <core::result::Result<T,F> as core::ops::try_trait::FromResidual<core::result::Result<core::convert::Infallible,E>>>::from_residual
             at /home/dotdev/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:2022:27
   2: signers_file::tests::test_propose_signers_file_with_master_signer
             at ./src/lib.rs:2949:9
   3: signers_file::tests::test_propose_signers_file_with_master_signer::{{closure}}
             at ./src/lib.rs:2935:58
   4: core::ops::function::FnOnce::call_once
             at /home/dotdev/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
   5: core::ops::function::FnOnce::call_once
             at /rustc/17067e9ac6d7ecb70e50f92c1944e545188d2359/library/core/src/ops/function.rs:250:5
   6: test::__rust_begin_short_backtrace
             at /rustc/17067e9ac6d7ecb70e50f92c1944e545188d2359/library/test/src/lib.rs:638:18
   ...

but ./src/lib.rs:2949:9 is the call to a function I write in the lib under test, which then further calls other functions I wrote, possibly in another local crate that I import in Cargo.toml.
In the end I don't know which line of my code causes the error.

How can I know which line of my library's code causes the problem?
I'm using dbg!(), but I suspect there's a more efficient way. What is it?

It's line 2949, column (character) 9 in ./src/lib.rs where the last call of your library occurred.
Without seeing the actual code, I doubt that anybody can say more than that.

Thanks for your reaction.

I realise I did not expressed myself clearly, sorry.

My question is actually more general and the backtrace provided only an illustration of the problem I try to solve. In the rust backtrace the last call I can identify is the function call in the test. Can I get a deeper backtrace? This depth of backtrace is ok when an assert fails, but here's it's a function call that causes an error. Can I get a trace of the deeper function calls?

In debug mode you usually get the full stack trace if the RUST_BACKTRACE=1 is set:

Which means, that in your example, this should be the very location where the bug is located.

This even works for tests:

Well, I identified the problem, and the IO error was due to a file move of an inexisting file.
The line reported by the error is

        propose_signers_file(root_dir, &proposal_content, &signature, pubkey)?;

which is a function I wrote. So it it true that this line is leading to the error, but there are further calls from insode propose_signers_file leading to the problematic file move, which is the operation I would have liked to easily locate.

Rust doesn't know why the function failed. It only knows that you return a Result by means of ? and you later try to unwrap it.
As far as I know there is no default tooling to dive deeper into the branch conditions etc. that lead to the returning of a Result::Err.

1 Like

The backtrace you have so far was automatically captured by anyhow at the point where the error was first converted to anyhow's error type. You can capture your own deeper inside your logic, if you control the error types involved.

However, in the cases where this is possible, if this is a one-time need for debugging and not a recurring need, it is probably simpler to temporarily insert a panic in lieu of error returning.

2 Likes

strace -kZff --trace=%file <your command>