Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GDB: How to force a watchpoint to not be deleted after a function returned?

Watchpoints on function-local variables usually get removed upon the function return, with a message «Watchpoint 7 deleted because the program has left the block in». Illustration:

struct mystruct{
    int a, b, c;
};

void MyFunc(){
    mystruct obj;
    obj.a = 2;
}

int main(){
    MyFunc();
}

gdb session example

(gdb) b 7
Breakpoint 1 at 0x4004f1: file /tmp/test2.cpp, line 7.
(gdb) r
Starting program: /tmp/test2 

Breakpoint 1, MyFunc () at /tmp/test2.cpp:7
7               obj.a = 2;
(gdb) wa obj
Hardware watchpoint 2: obj
(gdb) c
Continuing.
Hardware watchpoint 2: obj

Old value = {a = 4195600, b = 0, c = 4195328}
New value = {a = 2, b = 0, c = 4195328}
MyFunc () at /tmp/test2.cpp:8
8       }
(gdb) c
Continuing.

Watchpoint 2 deleted because the program has left the block in
which its expression is valid.
main () at /tmp/test2.cpp:12
12      }

I tried casting it like wa *(mystruct *)&obj and wa *(mystruct *)(void*)&obj, to no avail.

I need it because GDB on embedded ARM device I'm working with is broken: sometimes it removes a watchpoint for no reason; backtrace then looks like lines marked with "??" signs, and a message about corrupted stack. Even though application is actually fine.

like image 464
Hi-Angel Avatar asked Sep 19 '14 16:09

Hi-Angel


1 Answers

As GDB: Setting Watchpoints says,

GDB automatically deletes watchpoints that watch local (automatic) variables, or expressions that involve such variables, when they go out of scope, that is, when the execution leaves the block in which these variables were defined.

However, as of release 7.3 (thanks to @Hi-Angel and user parcs on IRC for pointing this out; I missed seeing it right there in the documentation), the watch command accepts a -location argument:

Ordinarily a watchpoint respects the scope of variables in expr (see below). The -location argument tells GDB to instead watch the memory referred to by expr. In this case, GDB will evaluate expr, take the address of the result, and watch the memory at that address. The type of the result is used to determine the size of the watched memory.

On older versions of GDB, you can run this instead, using the example from your question:

eval "watch *(mystruct *)%p", &obj

Note that watching locations on the stack may cause spurious notifications if the memory you're watching gets reused by another function's local variables.

As an alternative, you can automate the setting of a watchpoint on an automatic variable that keeps coming into and out of scope. Set a breakpoint at a point where it's in scope - for example, at the beginning of the function or block in which it's declared - then attach a watch and continue command:

(gdb) break MyFunc
(gdb) commands $bpnum
>watch obj
>continue
>end
like image 180
Mark Plotnick Avatar answered Sep 22 '22 13:09

Mark Plotnick