Search code examples
cgdbwatchpoint

Watching local variables in gdb without stopping execution


I am attempting to have GDB print the value of a variable when it changes.

Given an example program, I would like to get the value of x in func when it changes, but for the program to continue without prompt:

#include <stdio.h>
#include <stdlib.h>

int func(int x, int y);

int main(void) {

   int x = 5;
   int y;

   y = func(x, 4);

   printf("%d\n", x);
   printf("%d\n", y);
   return EXIT_SUCCESS;
}

int func(int x, int y) {
   y *= 2;
   x += y;
   return x;
}

What I have attempted:

break func
commands
 silent
 watch x
 commands
  continue
  end
 continue
 end

While this will successfully acquire the value of x when it changes, the problem is that when leaving the scope of x, gdb will stop to inform me that it is leaving the scope of x and that it is deleting the watchpoint. Is there any way to set GDB to go ahead and continue execution without a user prompt upon auto-removing a watchpoint?

I came across this question: gdb: do not break when watchpoint on local variable goes out of scope However it never did receive a solution.


Solution

  • You can give gdb's watch command the -l option, and the watchpoint won't be deleted (nor execution stopped) when the variable goes out of scope.

    But with this type of watchpoint, gdb will pick up changes that other functions make to that same address on the stack. So you can add the qualification if $_caller_is("func", 0) to the watchpoint so that gdb will only notify you if the variable changes within func.

    (gdb) list func
    18      int func(int x, int y) {
    19         y *= 2;
    20         x += y;
    21         return x;
    22      }
    (gdb) b func
    Breakpoint 1 at 0x400580: file s2.c, line 19.
    (gdb) set $funcbp = $bpnum
    (gdb) commands
    Type commands for breakpoint(s) 1, one per line.
    End with a line saying just "end".
    ># We can only set a watchpoint on a local var
    ># when it's visible, so we'll set it on entry to func.
    ># But we don't want to set it more than once
    ># if func is called more than once,
    ># so we disable the func breakpoint on first use.
    >disable $funcbp
    >watch -l x if $_caller_is("func", 0)
    >commands
     >continue
     >end
    >continue
    >end
    (gdb) r
    Starting program: /home/mp/s2
    
    Breakpoint 1, func (x=5, y=4) at s2.c:19
    19         y *= 2;
    Hardware watchpoint 2: -location x
    
    Hardware watchpoint 2: -location x
    
    Old value = 5
    New value = 13
    func (x=13, y=8) at s2.c:21
    21         return x;
    5
    13
    [Inferior 1 (process 29495) exited normally]