Skip to content

-Zinstrument-coverage producing coverage report which claims line is never run #84180

Closed
@alex

Description

@alex

I'm attempting to use -Zinstrument-coverage to measure coverage in a Python extension module (using pyo3). This is mostly working well. Except... there's a line that's getting recorded as not being executed, even though it is.

Exact steps for reproducing this can be seen in pyca/cryptography#5970. Specifically it's claimed that this line isn't covered: https://github.com/pyca/cryptography/blob/main/src/rust/src/asn1.rs#L40

That is line 40, a chained method call.

(I realize this is a somewhat involved example (there's Python! and numerous crates!), but I'm also not sure how to minimize it further. If there's any intermediate outputs I can produce, just ask!))

Looking at the raw llvm-cov show output, I see the following:

  | _RNvNtCslsOXpOCSGQA_17cryptography_rust4asn128___pyo3_raw_parse_tls_feature:
  |   36|      4|#[pyo3::prelude::pyfunction]
  ------------------
   37|      4|fn parse_tls_feature(py: pyo3::Python<'_>, data: &[u8]) -> pyo3::PyResult<pyo3::PyObject> {
   38|      4|    let tls_feature_type_to_enum = py
   39|      4|        .import("cryptography.x509.extensions")?
                                                             ^0
   40|      0|        .getattr("_TLS_FEATURE_TYPE_TO_ENUM")?;
   41|       |
   42|      4|    let features = asn1::parse::<_, PyAsn1Error, _>(data, |p| {
   43|      4|        let features = pyo3::types::PyList::empty(py);
   44|      5|        for el in p.read_element::<asn1::SequenceOf<u64>>()? {
                                ^4                                       ^0
   45|      5|            let feature = el?;
                                          ^0
   46|      5|            let py_feature = tls_feature_type_to_enum.get_item(feature.to_object(py))?;
                                                                                                   ^0
   47|      5|            features.append(py_feature)?;
                                                     ^0
   48|       |        }
   49|      4|        Ok(features)
   50|      4|    })?;
                    ^0
   51|       |
   52|      4|    let x509_module = py.import("cryptography.x509")?;
                                                                  ^0
   53|      4|    x509_module
   54|      4|        .call1("TLSFeature", (features,))
   55|      4|        .map(|o| o.to_object(py))
   56|      4|}
   57|       |

This confirms the same thing, that coverage thinks line 40 isn't being run. But we can tell it is, Line 42 is being run, and we can't get to line 42 without going through line 40 :-)

Meta

rustc --version --verbose:

rustc 1.53.0-nightly (07e0e2ec2 2021-03-24)
binary: rustc
commit-hash: 07e0e2ec268c140e607e1ac7f49f145612d0f597
commit-date: 2021-03-24
host: x86_64-unknown-linux-gnu
release: 1.53.0-nightly
LLVM version: 12.0.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-code-coverageArea: Source-based code coverage (-Cinstrument-coverage)C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions