rust-lang / backtrace-rs

Backtraces in Rust
https://docs.rs/backtrace
Other
537 stars 246 forks source link

resolve is off by one #465

Closed DzenanJupic closed 2 years ago

DzenanJupic commented 2 years ago

It appears, that resolve doesn't work correctly on Windows. When resolving function pointer addresses, the resulting Symbol is incorrect. Everything works fine when calling ptr.add(1) first.

Environment

Windows 10 Pro (10.0.19042 Build 19042)
backtrace = "0.3.64"
rustc 1.61.0-nightly (4ce374923 2022-02-28)
binary: rustc
commit-hash: 4ce3749235fc31d15ebd444b038a9877e8c700d7
commit-date: 2022-02-28
host: x86_64-pc-windows-msvc
release: 1.61.0-nightly
LLVM version: 14.0.0

Reproduce

# Cargo.toml
[package]
name = "temp"
version = "0.1.0"
edition = "2021"

[dependencies]
backtrace = "0.3.64"
// src/main.rs
fn main() {
    backtrace::resolve(test as *mut std::os::raw::c_void, |symbol| {
        println!("{symbol:?}");
    });
    backtrace::resolve(unsafe { (test as *mut std::os::raw::c_void).add(1) }, |symbol| {
        println!("{symbol:?}");
    });
}

fn test() {}

cargo run:

Symbol { name: "temp::main::closure$1", addr: 0x7ff7ad8d1310 }
Symbol { name: "temp::test", addr: 0x7ff7ad8d13b0, filename: "C:\\Users\\info\\Code\\Rust\\temp\\src\\main.rs", lineno: 11 }
bjorn3 commented 2 years ago

See https://github.com/rust-lang/backtrace-rs/blob/38cb2d5562a3d1b3a66bc21360d91275ea55cc0a/src/symbolize/mod.rs#L123-L147 1 is substracted from the address as the return address of a call frame is just after the call instruction. We want the information of the call instruction rather than the next instruction.

DzenanJupic commented 2 years ago

I see, thank you. It would be great if that could be documented!

Though, when this only applies to the IP of a Frame, why is this adjustment also used for addresses? Wouldn't it make sense to only apply this in resolve_frame?

alexcrichton commented 2 years ago

This isn't something that should be worked around, if the ips coming out of this crate don't resolve to the right function that's a bug in this crate. It may be the case that Windows is already doing the subtraction for us to have the reported ip land on the call instruction instead of the instruction after the call instruction, unlike libunwind, which would mean that the -1 logic isn't required on Windows. I don't know dbghelp on Windows enough though to know if this is the case.

DzenanJupic commented 2 years ago

It would, nevertheless, be great if that could be documented.