[compiler-rt][InstrProf][CoverageMap] Invalid counters when I use runtime api to get coverage data

I try to use compiler runtime API to write coverage data.

__llvm_profile_write_buffer(Buffer)

I call the API every 2 minutes, when my program runs. At the same time, I process the raw coverage data to readable format which likes work in llvm-profdata and llvm-cov.

But I get some wrong coverage line counters as follows. These line are from one function of my program. It is no possible that it runs as so many times. I guess 18446744073709551229 is a negative number as counter type is uint64_t.

{"at":1120,"count":18446744073709551229},{"at":1121,"count":18446744073709551229},
....
{"at":1035,"count":18446744073709548358},{"at":1036,"count":18446744073709548358},
....

I try to find some traces in the source codes, I find this.

// llvm-project/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
....
  for (const auto &Region : Record.MappingRegions) {
    Expected<int64_t> ExecutionCount = Ctx.evaluate(Region.Count);
    if (auto E = ExecutionCount.takeError()) {
      consumeError(std::move(E));
      return Error::success();
    }
    Expected<int64_t> AltExecutionCount = Ctx.evaluate(Region.FalseCount);
    if (auto E = AltExecutionCount.takeError()) {
      consumeError(std::move(E));
      return Error::success();
    }
    Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount);
....

But pushRegion is define using void pushRegion(CounterMappingRegion Region, uint64_t Count, uint64_t FalseCount). We assign int64_t values to uint64_t values.

So I get the wrong counter.

I’m comfused how I get a negative counter. I guess it comes from profile counters are read and writed at the same time.

I try to use -fprofile-update=atomic, but it still have the same problem.

Is there any other have same problem? How can I fix it?

@hyp Hi, Alex. Do you have some idea about it?