rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.59k stars 12.62k forks source link

Coverage information is wrong when using tracing #131119

Open xd009642 opened 1 week ago

xd009642 commented 1 week ago

So found an interesting thing when developing cargo-tarpaulin and confirmed it exists also with cargo-llvm-cov and using the raw llvm tools. When #[tracing::instrument] is added to a function the function body is not included in the coverage instrumentation. This doesn't happen with #[tokio::main] and I'm yet to create a more minimal reproduction with a less intense proc macro.

Project setup:

cargo new --lib tracing-instrument
cargo add tracing

In src/lib.rs

use tracing::instrument;

#[instrument]
fn instrumented_function() {
    println!("Hello");
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn is_it_hit() {
        instrumented_function();
    }
}

If you run something like cargo llvm-cov --html on this project you'll see only #[instrument] is marked as covered. If we comment out #[instrument] then the function signature, body and closing brace are marked as covered regions of codes.

This suggests to me there's something a bit wrong with the llvm instrumentation setup and how it interacts with procedural macros.

xd009642 commented 1 week ago

After further searching this seems to be a duplicate of https://github.com/rust-lang/rust/issues/123567 I'll close this and put this in a comment there

xd009642 commented 1 week ago

Reopening my issue because the other one I realised was specifically about code within macro attributes whereas this is a far simpler usecase (in theory)

Further insight I put on there replicated here

One thing interesting, is with #[instrument] commented out there's one identified code region which covers the entirety of the function. With it uncommented there are two code regions both are on line 3 (so #[instrument]). One is columns 1-2 and the last is columns 13-14 (which is essentially the end of the attribute). Now this doesn't happen for #[tokio::main] which is just fairly simple case of a macro creating an object and doing a chain of methods on it and passing the source in.