Search code examples
c++debuggingvisual-c++breakpoints

Why does data breakpoint not work on unaligned address


In Visual Studio while debugging a C++ project, some data breakpoints never hit.

So I wrote some code for testing:

#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
}

As you see, in function test, the value of *p will be zeroed first, then it will be changed implicitly, I got a litte-endian CPU so it must be 65536.

If you set a data breakpoint on p (4 bytes) to detect the changing, you'll get two different results: hit or not. It depends on the address of that p pointed at.

In my testing code above, test #1 will hit and test #2 will not, the difference between #1 and #2 are the addresses returned by alloc(0) and alloc(2).

This article How to: Set a Data Breakpoint on MSDN does not talk about this.

Does data breakpoint not work on an unaligned address ?


Solution

  • The data breakpoints are set with the assistance of the CPU, using the debug registers on x86; about them, the Intel manual says (§17.2.5):

    Breakpoint address registers (debug registers DR0 through DR3) and the LENn fields for each breakpoint define a range of sequential byte addresses for a data or I/O breakpoint. The LENn 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.

    (emphasis added)

    So, the limitation is in hardware.