在 Visual Studio 中调试 C++ 项目时, 一些数据断点从未命中。
所以我写了一些代码进行测试:
#include <iostream>
#include <stdint.h>
void test(uint32_t* p)
{
*p = 0;
// set a data breakpoint on p
*((char*)p + 2) = 0x1;
std::cout << *p << std::endl;
}
uint32_t* alloc(size_t offset)
{
char* p = new char[sizeof(uint32_t) + offset];
p = p + offset;
return (uint32_t*)p;
}
int main()
{
test(alloc(0)); // test #1
test(alloc(2)); // test #2
}
如你所见,在函数测试中,*p的值会先归零, 然后它将被隐式更改,我有一个小端 CPU 所以它 必须是 65536。
如果在 p(4 个字节)上设置数据断点来检测变化, 你会得到两种不同的结果:命中与否。这取决于 p 指向的地址。
在我上面的测试代码中,测试 #1 会命中而测试 #2 不会, #1 和 #2 之间的区别是返回的地址 分配(0)和分配(2)。
本文How to: Set a Data Breakpoint MSDN上没有讲这个。
数据断点对未对齐的地址不起作用吗?
最佳答案
数据断点是在CPU的协助下设置的,使用x86上的调试寄存器;关于它们,英特尔手册说 (§17.2.5):
Breakpoint address registers (debug registers
DR0
throughDR3
) and theLENn
fields for each breakpoint define a range of sequential byte addresses for a data or I/O breakpoint. TheLENn
fields permit specification of a 1-, 2-, 4- , or 8-byte range, beginning at the linear address specified in the corresponding debug register (DRn). Two-byte ranges must be aligned on word boundaries; 4-byte ranges must be aligned on doubleword boundaries. I/O addresses are zero-extended (from 16 to 32 bits, for comparison with the breakpoint address in the selected debug register). These requirements are enforced by the processor; it uses LENn field bits to mask the lower address bits in the debug registers. Unaligned data or I/O breakpoint addresses do not yield valid results.
(强调)
所以,限制在于硬件。
关于c++ - 为什么数据断点对未对齐的地址不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24880636/