Setting GDB hardware watchpoint/how to set software watchpoint

后端 未结 3 660
故里飘歌
故里飘歌 2020-12-15 05:05

An earlier question explained that on x86 the size of objects being watched is limited by debug registers. As expected, I can \"watch\" a double variable. But I can\'t watch

3条回答
  •  半阙折子戏
    2020-12-15 05:36

    Short answer: Use watch -location pObject->dPrice, or the short form watch -l.

    Long answer: Quoting the GDB manual:

    Watching complex expressions that reference many variables can also exhaust the resources available for hardware-assisted watchpoints. That's because GDB needs to watch every variable in the expression with separately allocated resources.

    GDB quite literally watches the expression itself, not whatever address it points to. In this case, it means that the breakpoint will hit if pObject itself is changed to point to a new dPrice; there's not just a watchpoint for pObject->dPrice, but also one for pObject itself. This may be more than what's available.

    A more comprehensive example:

    // Set a watchpoint on '*p' before running
    #include 
    
    int a = 0;
    int b = 0;
    int c = 0;
    int* p = &a;
    
    int main()
    {
        puts("Hi"); // Dummy lines to make the results clearer, watchpoints stop at the line after the change
        *p = 1; // Breaks: *p was changed from 0 to 1
        puts("Hi");
        a = 2; // Breaks: a is *p, which changed from 1 to 2
        puts("Hi");
        p = &b; // Breaks: p is now b, changing *p from 2 to 0
        puts("Hi");
        p = &c; // Doesn't break: while p changed, *p is still 0
        puts("Hi");
        p = NULL; // Breaks: *p is now unreadable
        puts("Hi");
        return 0;
    }
    

    In theory, this is a useful feature; you can watch a complex expression, breaking as soon as it's false, somewhat like a constantly-tested assertion. For example, you can watch a==b in the above program.

    In practice, it's unexpected, often triggers this issue, and usually isn't what you want.

    To watch only the target address, use watch -location pObject->dPrice. (This is available as of GDB 7.3, released in July 2011; if you're using anything older, use print &pObject->dPrice and watch *(double*)0x12345678, or whichever address it prints.)

提交回复
热议问题