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

    <tr>
        <th>Summary</th>
        <td>
            lldb cannot single step over an Armv8.0-a atomic sequence
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            lldb
      </td>
    </tr>

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

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

<pre>
    Compiling the following source:
```
#include <atomic>

int main() {
 std::atomic<int> i(0);
    return ++i;
}
```
With:
```
$ g++ /tmp/test.cpp -o /tmp/test.o -g -march=armv8-a -O3
```
Produces an atomic sequence to do the `++i`. This sequence looks like:
```
 704: 885ffc20        ldaxr   w0, [x1]
 708:   11000400        add     w0, w0, #0x1
 70c:   8803fc20        stlxr   w3, w0, [x1]
 710:   35ffffa3 cbnz    w3, 704 <main+0x24>
```
As it happens, if you breakpoint `main` here with a software break, it will be on the first ldaxr. What's supposed to happen is when you load some value, do the add, then attempt to store it to memory. If anything has changed memory (in general, I think, not sure how specific it gets) the store will return a failed flag.

That failure is caught by the cbnz and you loop again to make another attempt.

What actually happens when you've breakpointed one of the atomic instructions is that whatever memory modification flag gets reset each time, so you never leave the sequence.

Output from lldb:
```
$ ./bin/lldb /tmp/test.o
(lldb) target create "/tmp/test.o"
Current executable set to '/tmp/test.o' (aarch64).
(lldb) b main
Breakpoint 1: where = test.o`main + 36 [inlined] std::__atomic_base<int>::operator++() at atomic_base.h:319:34, address = 0x0000000000000704
(lldb) c
error: Command requires a current process.
(lldb) run
Process 3673703 launched: '/tmp/test.o' (aarch64)
Process 3673703 stopped
* thread #1, name = 'test.o', stop reason = breakpoint 1.1
    frame #0: 0x0000aaaaaaaaa704 test.o`main [inlined] std::__atomic_base<int>::operator++(this=0x0000fffffffff2a0) at 
<...>
(lldb) c
Process 3673703 resuming
Process 3673703 stopped
* thread #1, name = 'test.o', stop reason = breakpoint 1.1
 frame #0: 0x0000aaaaaaaaa704 test.o`main [inlined] std::__atomic_base<int>::operator++(this=0x0000fffffffff2a0) at
<...>
(lldb) c
Process 3673703 resuming
Process 3673703 stopped
* thread #1, name = 'test.o', stop reason = breakpoint 1.1
 frame #0: 0x0000aaaaaaaaa704 test.o`main [inlined] std::__atomic_base<int>::operator++(this=0x0000fffffffff2a0) at
<...>
(lldb) dis
test.o`main:
<...>
->  0xaaaaaaaaa704 <+36>: ldaxr  w0, [x1]
```
This will go on forever as the atomic store never succeeds.

GDB is able to stop here and continue normally, it is my understanding that it is detecting these sequences.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsV0tv67gV_jX05sACRfq58CKOJ8WspkAHmOXFMXkksZFIDUnFSX99QVK2E987RRdF28UIhgyJ5_mdpzAE01qiA1sf2fq0wCl2zh9O-Gb030ajXinGxdnpj8OzG0bTG9tC7Aga1_fukp6Cm7wiJp8YPzH-xDZ8_pVHIY1V_aQJmHzG6AajmPxpPsx3YyMMaCwTOyb2wLbH8h5C1EmsfLqyPRsbmfwJDBM7zsSeySspAHiKk7fAxJGJo7kdse3ph4b9ZmL3x0avoC2CgImXOIzpTiFWahxh6R5eOli2sBzQq47JE_rhbbdEWP4ifyj8r97pSVEAtFAcg0C_T2QVQXSgXcY3kc-ebHgFv3Ym3Ml6514D9Ob1D2GHLV8x-QS73bpplOAwX73Gdw8AF87EM7D18b1m69ONZ5d4AOqac77iNy7UOv8XrplXSP5e3zhV4dztuPysL8S-6JOfOB-01rzwynXTNA1KUGf7D7gxbfkqpU7JkCN_F6t7_nx1-imAidDhOJINidU08OEmOHvC19GlPGMbngVtOHTkCS4mdoAQXBMv6KmQZtYIF9P3cCZwtmS88SEWACv4rcPIxDZAmMbRBdIpdEUzmACXjmxW3TvUENxA8Ib9REnyHGDUOj3FRIkx0jDGJCNE5ylpjw4GGpz_qODnBtB-xC5VW4cBVIe2JT2fAxM7Y6ElSx77JPNnSLTZDesihMkTdO4CYSRlGqOS-JZiSNWWTCk6s7tzESE0aHrS0PTYVp-L9dcOYz5MQk0AhVPbRTh_ZEk5cmj17LsbAVs0NjuDrwRoXezIXx3-IjlBCqjihH3_cY3iDUkmtm_0KZKkwVkC1xQwSx0ZG6KfVDTOhmRcTCIvHUZ6I3-Fa3A6gYCJKvuXsQBPgSIQqg6iGXKkgst-2MzdE75RgWsuwy_W_zLFcYrQeDdA3-vzv2otFRMv55TNL4nysZlc6XZZTAoR-pYiKE8YCZgQjwxCFJ7nyXuyEeid1BTx3CdbcyYxsf2OaZsSB1PT2qyY2Fff6T2XrpxfH-8lVKdqveTqYfIEs7hSV6n7gtykEje2N5Y0W5_uffzbtxKob2cMdGvn5cyN5DE6X7rePAtSRtw5qtSwZb1P91UKEGrtKYRsB3_nn6_U_x4dUuUNee98cuLZDUNKVk-_T8anjgxqhnD0TlEI34PiJ3tr44kC5GYrt1xCj5NVHSVP_x24fywkRDeOpK9anyB2nlCnZlvncsahoM7E9iY4p2p0I3jC4Gw-_9Ty6qq-D8nGZwlC5p5bMMPrlTrtQzj_A3GMnQlMnoqu5noJ5HOAZ2flc1VV987-XdQeofIUpsHY9n8B5P8fin-C-F8AUZtQ3n2x7N7pvzIu06YK_P2LT0w-M3GUm2LjdR370V70MDfyAphHdOvSRtI4n8cShs8DsEzyMrDCpBSRDl_G1F9OxzQY82wo28ZYFqHUB5Wz0diJwDo_pCk8L0ImwPABk9XkQ0SryzcAxvlMUyQV5w-DcJ-PoVrog9R7uccFHerNdrXe8t16vegO21pgU9NebDbnTUP1Xq-2et3IZnWWhOvzwhwEF5LXYlWv5KpeV3W9V7hfC87XukHF2YrTgKav-v5tqJxvFyaEiQ4bLtb7RY9n6kP-phGihE-krxt_SOTL89QGtuK9CTHcBUQTezrkkazQ5s3J2DYN0UgjuIy2hae03ld8iY_L-2Ly_aGLcQwpI8QLEy-tid10rpQb8qx_u_4tR-_-Tioy8ZKtDky8ZMP_GQAA__--qBJB">