<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - TestConcurrentTwoWatchpointsOneSignal flaky on linux arm64"
   href="https://bugs.llvm.org/show_bug.cgi?id=35228">35228</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>TestConcurrentTwoWatchpointsOneSignal flaky on linux arm64
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>lldb
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>lldb-dev@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>labath@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>I've managed to figure out *what* is happening, but right now I have no idea
why is that.

The trick here is that the variables g_sigusr1_count and g_watchme are next to
each other in memory. Due to linux ptrace limitations setting a watchpoint on
g_watchme also watches the memory covered by g_sigusr1_count. Now that normally
shouldn't matter, as we have code to recognise these "false" watchpoint hits
and ignore them. However, fun things start to happen when two threads hit the
watchpoint simultaneously (one false, one real). The abridged packet log is as
follows:

lldb<   5> send packet: $c#63
lldb<1357> read packet: $T05
lldb<  16> send packet: $jThreadsInfo#c1
lldb< 579> read packet:
$[{"name":"a.out","registers":{"29":"d0fbffff7f000000","30":"98ffd4b77f000000","31":"90fbffff7f000000","32":"ec55d0b77f000000"}],"tid":3072}],{"description":"366504129148
3
366504129148","name":"a.out","reason":"watchpoint","registers":{"29":"90e465b77f000000","30":"7c32595555000000","31":"40e465b77f000000","32":"e8a1555555000000"}],"signal":5,"tid":3075}],{"description":"366504129148
3
366504129144","name":"a.out","reason":"watchpoint","registers":{"29":"901456b77f000000","30":"7832595555000000","31":"401456b77f000000","32":"e0a0555555000000"}],"signal":5,"tid":3076}]]#b9
======= two threads hit the watchpoint: one false-positive, one real
lldb<  19> send packet: $z2,555559327c,4#79
lldb<   6> read packet: $OK#9a
lldb<  16> send packet: $vCont;s:0c03#e8
lldb<1187> read packet: $T05
===== disable watch, single step on first thread
lldb<  16> send packet: $vCont;s:0c04#e9
lldb<1089> read packet: $T05
===== single step on second thread
lldb<  19> send packet: $Z2,555559327c,4#59
lldb<   6> read packet: $OK#9a
lldb<  19> send packet: $z2,555559327c,4#79
lldb<   6> read packet: $OK#9a
lldb<  19> send packet: $Z2,555559327c,4#59
lldb<   6> read packet: $OK#9a
lldb<  19> send packet: $z2,555559327c,4#79
lldb<   6> read packet: $OK#9a
lldb<  19> send packet: $x...
lldb<2052> read packet: $...
===== twidlling the watchpoint(????), then reading the variable memory 
lldb<  19> send packet: $Z2,555559327c,4#59
lldb<   6> read packet: $OK#9a
lldb<  19> send packet: $z2,555559327c,4#79
lldb<   6> read packet: $OK#9a
lldb<  16> send packet: $vCont;s:0c04#e9
lldb<1089> read packet: $T05
===== more twiddling, then another single step (!!!!!). At this point we are
definitely doing something wrong. There is no need for two single-steps on the
second thread
lldb<  19> send packet: $Z2,555559327c,4#59
lldb<   6> read packet: $OK#9a
lldb<  19> send packet: $z2,555559327c,4#79
lldb<   6> read packet: $OK#9a
lldb<  19> send packet: $Z2,555559327c,4#59
lldb<   6> read packet: $OK#9a
Process 3072 stopped
  thread #2, name = 'a.out', stop reason = trace
    frame #0: 0x000000555555a1ec
a.out`watchpoint_func(input=0x0000000000000000) at main.cpp:79
   76       do_action_args(input);
   77   
   78       g_watchme = 1;     // watchpoint triggers here
-> 79       return 0;
   80   }
   81   
   82   void *
* thread #3, name = 'a.out', stop reason = watchpoint 1
    frame #0: 0x000000555555a0e8 a.out`signal_func(input=0x0000007fb75614b0) at
main.cpp:70
   67       // pthread_kill(pthread_self(), SIGUSR1);
   68   
   69       g_sigusr1_count += 1;
-> 70       return 0;
   71   }
   72   
   73   void *
===== now lldb reports the watchpoint hit on the "false" thread, whereas the
thread that really hit the watchpoint reports stop_reason=trace :/</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>