Search code examples
windbgcdb

How to set a data breakpoint on a variable address in CDB (WinDbg)


class Test
{
public:
    Test() 
    { 
        std::cout << "ctor" << std::endl; 
        ptr = new int(5);
        *(ptr + 1) = 42;
    };
    ~Test() { std::cout << "dtor" << std::endl; };

    int* ptr;
};

void foo()
{
    Test test;
}

int main()
{
    foo();
    return 0;
}

In the above example I want to set a data breakpoint at the address pointed to by ptr plus an offset (4 bytes in this case), to detect the heap corruption.

After I break inside the Test constructor, I have tried using the following to set the breakpoint but have failed:

0:000> ba w 4 (ptr + 4)
Bp expression '(ptr + 4)' could not be resolved, adding deferred bp
*** Bp expression '(ptr + 4)' contains symbols not qualified with module name

If I put the address manually then it obviously works. But I don't want to hard code the address in the command because I am doing this as part of a script and the address inside ptr can change every time.

What is the correct syntax for adding the data breakpoint without hardcoding the address?


Solution

  • You need @@c++() or .expr /s c++:

    0:000> bp MemoryBreak!Test::Test
    
    0:000> g
    Breakpoint 2 hit
    MemoryBreak!Test::Test:
    [...]
    
    0:000> l+t
    Source options are 1:
         1/t - Step/trace by source line
    0:000> p
    MemoryBreak!Test::Test+0x42:
    
    0:000> ? @@c++(ptr)
    Evaluate expression: 2790386541360 = 00000289`afffa330
    
    0:000> ba w 4 @@c++(ptr)+4
    0:000> bl
         1 e Disable Clear  00007ff7`5fac2720  [C:\....cpp @ 23]  0001 (0001)  0:**** MemoryBreak!main
         2 e Disable Clear  00007ff7`5fac1fa0  [C:\....cpp @ 6]  0001 (0001)  0:**** MemoryBreak!Test::Test
         3 e Disable Clear  00000289`afffa334 w 4 0001 (0001)  0:**** 
    
    0:000> g
    Breakpoint 3 hit
    MemoryBreak!Test::Test+0xa7: