Reputation: 341
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.
Upvotes: 6
Views: 610
Reputation: 341
Thank you both @derobert and @peter! I finally went back to this, and this:
break main
commands
watch somevar
commands
cont
end
cont
end
run
does the trick. This works when "somevar" is global, or local to "main". If "somevar" is local to anther function, just replace "main" with that function name above.
Put these commands in a file (e.g. "gdbscript") and run gdb like:
gdb -x gdbscript a.out
Upvotes: 1
Reputation: 999
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.
Upvotes: 3
Reputation: 51197
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.
Upvotes: 6