tags:

views:

124

answers:

2

I have an application. I have the source code (in C). I can compile it anyway I want. Add whatever tool I want to it. Etc. However, I do not want to pepper the source code with a bunch of printf's. I want to be able to produce a log of some sort that shows when a particular value (some member of a global structure for example) is written to (its value changes). I'd like to be able to show source file and line number, and the old and new value.

I'd also like to be able to specify the value by name, not address. But address is OK. Bonus points if I can specify a value that is local to a function.

I'm still scratching my head trying to figure out gdb's trace commands. Any help is greatly appreciated. Thanks.

+4  A: 

First, you'll need to make sure to compile your program with debug symbols, and probably w/o optimization to make gdb most useful. For gcc, that'd be -g -O0.

Second, the feature you're looking for isn't tracing, its watchpoints.

(gdb) help watch
Set a watchpoint for an expression.
A watchpoint stops execution of your program whenever the value of
an expression changes.

So, given some example code:

int main() {
    int a;
    a = 1;
    a = 2;
    return 0;
}

you can then run gdb on it, and:

(gdb) b main
Breakpoint 1 at 0x80483a5: file test.c, line 4.
(gdb) run
Starting program: /tmp/test 

Breakpoint 1, main () at test.c:4
4               a = 1;
(gdb) watch a
Hardware watchpoint 2: a
(gdb) c
Continuing.
Hardware watchpoint 2: a

Old value = -1207552288
New value = 2
main () at test.c:8
8               return 0;

it's working slightly funny due to a being on the stack, not memory. And if optimization were on, it'd work even less: a would be optimized out.

derobert
Try declaring `a` as `volatile int`, that may make the example work better.
caf
Thanks derobert. From what I understand about watches is that they cause program execution to cease until the user "continues". I'm sure I could write an expect script to do this, but is there someway to do this automatically from within gdb?
tvaughan
@tvaughan: I don't know of an automatic way to do it within gdb.
derobert
@tvaughan: Though gdb does have a (optional) built-in Python API, which you may be able to use. `info gdb Extending Python` should get you there.
derobert
+2  A: 

As stated already, you need to set a watchpoint on your variable.

The you use the "commands" command

(gdb) help commands
Set commands to be executed when a breakpoint is hit.
Give breakpoint number as argument after "commands".
With no argument, the targeted breakpoint is the last one set.
The commands themselves follow starting on the next line.
Type a line containing "end" to indicate the end of them.
Give "silent" as the first line to make the breakpoint silent;
then no output is printed when it is hit, except what the commands print.

So, find the watchpoint number from the watch command, and do this (assuming your watch is the second break)

(gdp) commands 2
> print a
> cont
> end

Assuming a is the variable you want. You can leave out the print line if you're happy with the output gdb gives you anyway.

You can also use the commands in your original breakpoint to set the watchpoint and continue.

Peter