9

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.

Hi-Angel
  • 4,933
  • 8
  • 63
  • 86

1 Answers1

8

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
Mark Plotnick
  • 9,598
  • 1
  • 24
  • 40
  • Okay, but aren't this way `wa *(mystruct *)&obj` I'd force gdb to watch a just a piece of memory rather than variable that have a scope? – Hi-Angel Sep 20 '14 at 08:25
  • Btw, I can't set the `commands` because I have no even an idea where is in the real code the problem occurs when gdb thinks that a variable gone from a scope. As I mentioned gdb doesn't even shows an adequate backtrace in the moment. – Hi-Angel Sep 20 '14 at 08:31
  • I've added a description of a way to create a watchpoint for an area of memory using a raw address. It won't be automatically deleted by GDB. Keep in mind that, after a function returns, the memory used for automatic variables can be reused by subsequent function calls, so a watchpoint of a raw address on the stack may show irrelevant changes. – Mark Plotnick Sep 20 '14 at 22:31
  • 3
    On IRC #gdb parcs also gave much easier solution: just to use `watch -l obj`. – Hi-Angel Sep 21 '14 at 12:52
  • @Hi-Angel I didn't know that, thanks. That's better than my answer. If you'd like to add that as your answer and accept it, I will delete my answer. – Mark Plotnick Sep 21 '14 at 13:27
  • No need for this, your answer is good too. You may just upvote the comment in order to be on the top for anyone who could read this. Or even better: you may edit your answer(just I am not very good in English) to add one more solution. – Hi-Angel Sep 21 '14 at 13:56
  • 1
    OK, I see that `-location` was added in GDB 7.3. I've updated my answer. Thanks to you and parcs. – Mark Plotnick Sep 22 '14 at 15:17
  • Unfortunately, with the last recommendation, GCC will also break (by the watchpoint) everytime that the function returns, when it has deleted the watchpoint. – Johannes Schaub - litb May 14 '19 at 16:55