Skip to content

[coverage] support source-based static destructor coverage #150440

@justincady

Description

@justincady

It appears executed static destructors are not reported for code coverage:

// coverage.cc
#include <cstdio>

struct C {
  C() {
   printf("ctor called\n");
  }
  ~C() {
   printf("dtor called\n");
  }
};

static C c;

int main() {
  printf("main\n");
  return 0;
}
# build-cxx.sh
/usr/bin/clang++ --version | /bin/grep "clang version"
/usr/bin/clang++ -fprofile-instr-generate -fcoverage-mapping coverage.cc -o coverage
./coverage
/usr/bin/llvm-profdata merge -sparse default.profraw -o default.profdata
/usr/bin/llvm-cov show ./coverage -instr-profile=default.profdata
$ ./build-cxx.sh coverage.cc
clang version 22.0.0
ctor called
main
dtor called
    1|       |#include <cstdio>
    2|       |
    3|       |struct C {
    4|      1|  C() {
    5|      1|   printf("ctor called\n");
    6|      1|  }
    7|      0|  ~C() {
    8|      0|   printf("dtor called\n");
    9|      0|  }
   10|       |};
   11|       |
   12|       |static C c;
   13|       |
   14|      1|int main() {
   15|      1|  printf("main\n");
   16|      1|  return 0;
   17|      1|}

I believe this is because ~C() runs after static destruction triggers coverage output to be written via __llvm_profile_write_file (checked with GDB).

It seems this was fixed for gcov (--coverage) years ago:

@MaskRay could we extend this fix to source-based code coverage?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions