松弛内存模型上的断点行为

Behavior of breakpoint on relaxed memory models

Init: int x = y = 0;

thr1       thr2
----       ----
y = 1;     x = 1;    WRITE to global variables
a = x;     b = y;    READ from global variables
print(a);  print(b);

在TSO内存模型下的上述代码片段运行中,众所周知两个线程可以同时打印0,因为一个CPU可以重新排序在写指令之前执行读指令(即线程的第二行)的指令。

那么,我们在读取的指令上打断点,遇到断点什么都不做,继续执行会怎样?两个线程仍然可以同时打印 0,还是断点可以防止重新排序?

我假设 x86-64 架构和 x86-TSO 内存模型。如果给出体系结构(或内存模型)之间的任何差异,我们将不胜感激。 此外,我猜硬件断点和软件断点不会对结果产生影响(因为它们都会触发异常,并且 x86 架构对它们的处理方式类似)。这个猜测是否正确?

我假设这是汇编的伪代码(不是 C,其中可能会发生大量编译时优化),对于与 https://preshing.com/20120515/memory-reordering-caught-in-the-act/ 相同的情况,其中 StoreLoad 重新排序将是可见的。

带有断点处理程序的断点 returns 只是序列化指令(如 CPUID 或 IRET)的一种非常昂贵的替代方法,它确保所有先前的指令都已执行,并且所有先前的存储致力于连贯缓存(即耗尽存储缓冲区)。

原因是从断点返回可能会涉及到IRET一条序列化指令。 (像 MFENCE 但也序列化乱序执行)。

所以是的,断点是其他线程观察到的内存重新排序的完整障碍。

这适用于硬件断点或调试器必须恢复原始指令的第一个字节以使其正常执行的软件断点,而不是 0xcc int3 软件断点。