<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/62558>62558</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Data race in Source-based Code Coverage
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          Dushistov
      </td>
    </tr>
</table>

<pre>
    I run two test functions, each on its own thread. Both of these function test the same functionality.
As result each line of tested code should executed two times.
But time to time the execution counter for lines is different.

My code
```c++
#include <string>
#include <string_view>
#include <cassert>
#include <thread>

struct State {
  std::string data;

  static State parse(std::string_view src) { return State{std::string(src)}; }

  bool has(std::string_view needle) const {
    return this->data == needle;
  }
};

void state_has_true() {
  const auto s = State::parse("value");
  assert(s.has("value"));
}

void state_has_false() {
  const auto s = State::parse("value");
  assert(!s.has("missing"));
}

int main() {
   std::thread t1(state_has_true);
   std::thread t2(state_has_false);


  t1.join();
  t2.join(); 
}  
```

If run:
```
clang++ -std=c++17 -Wall -Wextra -pedantic -fprofile-instr-generate -fcoverage-mapping foo.cc -o foo
LLVM_PROFILE_FILE="foo.profraw" ./foo
llvm-profdata merge -sparse foo.profraw -o foo.profdata
llvm-cov show ./foo -instr-profile=foo.profdata | grep -E '^   ( 9|1[1-3])' 
    9|      2|  static State parse(std::string_view src) { return State{std::string(src)}; }
   11|      2|  bool has(std::string_view needle) const {
   12|      2|    return this->data == needle;
   13|      2|  }
```

But if I run such script test.sh:

```bash
#!/bin/bash

set -euo pipefail

make
export LLVM_PROFILE_FILE="foo.profraw"
for i in $(seq 1 15000); do
    rm -f $LLVM_PROFILE_FILE foo.profdata
    ./foo
    llvm-profdata merge -sparse foo.profraw -o foo.profdata
    if [ ! -z "$(llvm-cov show ./foo -instr-profile=foo.profdata | grep -E '^   ( 9|1[1-3])' | grep -v  '|      2|')" ]; then
        echo "Found BUG at step $i"
        llvm-cov show ./foo -instr-profile=foo.profdata
        exit 1
    fi
done
```

then after some time I got:

```
❯ sh test.sh 
make: «foo» не требует обновления.
Found BUG at step 460
    1|       |#include <string>
    2|       |#include <string_view>
    3|       |#include <cassert>
    4|       |#include <thread>
    5|       |
    6|       |struct State {
    7|       |  std::string data;
    8|       |
    9|      2|  static State parse(std::string_view src) { return State{std::string(src)}; }
   10|       |
   11|      1|  bool has(std::string_view needle) const {
   12|      1|    return this->data == needle;
   13|      1|  }
   14|       |};
   15|       |
   16|      1|void state_has_true() {
   17|      1|  const auto s = State::parse("value");
   18|      1|  assert(s.has("value"));
   19|      1|}
   20|       |
   21|      1|void state_has_false() {
   22|      1|  const auto s = State::parse("value");
   23|      1|  assert(!s.has("missing"));
   24|      1|}
   25|       |
   26|      1|int main() {
   27|      1|   std::thread t1(state_has_true);
   28|      1|   std::thread t2(state_has_false);
   29|       |
   30|       |
   31|      1|  t1.join();
   32|      1|  t2.join(); 
   33|      1|}  
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEWN1u47oRfhr6ZiBDpCT_XPgisuMiwC5adNHuZUBLI4tbWXRJysn26YuhZFtWouxmc86ewJCt4Td_nBnOMNJata8RVyxJWbKZyMaV2qw2jS2Vdfo02en8--oBTFODe9Lg0DoomjpzSteWiTWgzErQNShnQT_V4EqDMp9Cql0JugBXosULSyvAlQhWHq5kWSn3fcrCDQvv7iwYtE3lWtGVqtHLQeswh0znCLbUTZUDPmPWENFbpg5oOxFp4_w7ON19l9ihyYZMN7VDA4U2XrwFZSFXRYEGa9fJaJ-fv3uNHWkWtp-MiZQ-LVVEqs6qJkdg0do6o-o9i-7HFx9PCp9GEJm0Fo0bWW339rron9aZJnPwxUmHwOadVQDW5Sy6Y9FdqxVy6SSL0j4rgaRTWcd8lMYiE4sBp7cXrMmYWJICMOgaU7dMbJ4O4CTAY9l8w6IU6OtG507rCkppxzTViHmFpCzTtXV9n-Cs25XKBiy6J6eARRsWbc580QV91ewt6Vtx0ir3zuNjKe2jMw053jl45m_Vy8ZpsKSk89gbfN4rJsRJVsQtyOWr8i6QYmGnra8DZA882KGBbYWs7J9mHBO8Z99BWesj-AMLVe3gIFX90qpr1rW5Co77MN9udN-UlxzihqNzfzkI4Jnd8ek3fbakJ9aJWzpcHAEYVHNf4ENBRx3Z8xomqyTtDtU-BN7uTXcU8DkEX2VVQfAVn52REBwxlzXVVlAcjS5UhYGqrTPBHms0VG5BkekTGrnH4CCPR6rRQutplkGg6Ver89Onf39-_Mc__759-HT_SA_KdiEISXKNfGJCwJSJ7YWlqk6HgBZ9dRzQ7BEC65MCenydmukZ2WPO9IkO2aezXOhs7zxh0abPCGy-hr3BIwT3wMScJfcAwMQClmy-5ixJeRCxZOOTag7XYqZl8H_C__qdpxEAcD7Q_5GTiYuBsPedVcCjAf-15l5LVGpxqoC2M9smK8FmRh2d75NTW15T-FbGTtry0lqY4Exsd1Qm295C21bQQYCNhqM6YiFV1V88yP90PRGfj9o4-KksbTmo6ypQNTAR00bjf4EDT8Iw7Co1173j_gBBQcgXCl5JXWK4KQQifKgYSIAqgCUpMMEh-B_4s5Hs_g11ckGfwMP7-UHvBBNADFFKI059NZr-MCs12bvVTZ1D-q-_gXRgHR5pP9UlHmf4Lzg00PesHPArrVDt71zXwwGqn0tkOMiCBjKraVajge0B9tqN5XD3ei_YcsPutmDLc9ZDLz2jO2Brwe5SSoe1YGkKbBOydOOfCbANZwvhn2FL8k_uKdGZQpiW7_68fJHRUoR_pj0R7erCM2-7cfJlEOKzI7RX15MIfHDfGCn7J8w4_HbIJGD0Bs9w7CRQ_AZ-MIgSJrmFX-izG_rYsAowv8H9YHwl1GJE4V_dVMLX7eo1G_5HNhv-wWbDb5sNUQaR7w3PtDoSaD67EflTAzbw-cCOD021wBcDce8YwolnecPe3xMxElXB3_J6ZHQHMQzfx9wWw2i-d7wnGfG47yMRF7cRf-NSIIZh_oVrghjG9t0XBxKyfN2VaCS80bBox64bEA1DOnIBIWg03OoXV5JJvoryZbSUE1zx2SISURxHYlKu4mSBHGcxJjO-C-UuzjkW8TxM4jjJwmQ2USsRiihMwljwcM7FNFvMkvluV8yXmO1i3LE4xINU1ZT6_VSb_URZ2-BqJpJkMankDivr_xskRI1P4BcpY5LNxKz8jLBr9pbFYaWss1cpTrkKVxs6dozMkAa8L7oxGQY7aTGHtc4R1t2FZ9KYalU6d7QUQbFlYrtXrmx200wfmNiS1O6LRo9vmDkmtt4Wy8TW2_r_AAAA__93Ah5m">