GDB structure output - c

I haven't worked with gdb for a long time and this feels like a basic question.
I am trying to observe a structure as it changes but rather than break at a specific point and print it out I'd rather let the application run as normal and give me a snapshot of the structure at a specific point. Think a breakpoint that performs an action (print struct) rather than pausing execution.
I am interested in looking at the changes to the structure all at once rather than incrementally. I can get what I want through printf, but gdb is much more elegant.
Update: Thank you for all the responses. I want to watch one struct at a particular point and the commands solution is just what I needed. This has been very helpful.

A nice approach is to set a breakpoint with associated commands, e.g:
break main.c:100
commands 1
print data_structure
continue
end
This runs the two commands print data_structure and continue whenever breakpoint 1 is reached.

If the information held by your data structure might be changed by several code lines, you can also use gdb's watch. Note that it is horribly slow so it should be used carefully. The commands part is just the same.
(gdb) break main
Breakpoint 1 at 0x80483b5:
(gdb) run
Breakpoint 1, main ()
(gdb) watch data_structure
Hardware watchpoint 2: data_structure
(gdb) commands 2
Type commands for when breakpoint 2 is hit, one per line.
End with a line saying just "end".
> print data_structure
> continue
> end
(gdb) continue

Related

GDB - show last n lines executed

Sometimes in GDB I want to see the control flow that got the program to where it is now. Simply put, how do I make GDB print the last x lines executed?
This is yet another use case for Reverse Debugging.
You should start process record and replay at some point:
(gdb) record
When you want to see last executed lines you can go backwards like
this:
(gdb) reverse-step 3
or
(gdb) reverse-next 3
Use this answer https://stackoverflow.com/a/1545732/72178 to actually
print the next N executed lines.
You simply cannot do that (easily) in gdb, because the execution trace of any program is not kept (and keeping it would be very expensive : it would slow down a lot the execution, and it would use a lot of resources - memory & disk space).
You can however use the backtrace or bt command of gdb to show the call stack, that is the current instruction pointer in the current function, the calling function, the calling function of the calling function, and so forth
BTW, if you really wanted it, you might script recent gdb using Python or Guile to give you such information. You certainly could keep the entire trace (by scripting around the step & backtrace functionalities).

how to return to main function in gdb

I'm using gdb for debugging
I get a segmentation fault, and then I want to set another break point in the main function and run the program from the beginning
however, although I have finished the current run
and it shows "THe program is not being run"
when I input 'list'
it shows a code snippet of a libarary file
it means currently I'm not in the main function
If I re-run the program, even if I set the break point at the beginning of the main()
it still get segmentation fault, it means the program is running within the library file
so how to return to the main() function?
thanks!
tips: I'm using libpcap.h and I have a '-lpcap' option when compiling
BTW, when I use break 9
to set a breakpoint at 9, gdb runs the program to the 11-th line? what is wrong with this inaccuracy? thanks!
Simply re-issue the run command. You will lose program state, but not breakpoints which seems to match what you need.
"BTW, when I use break 9 to set a breakpoint at 9, gdb runs the program to the 11-th line" - from this, and other information you've provided, it sounds like perhaps the source code is out of sync with gdb's mapping of addresses to source lines. Have you by any chance been editing the program? Have you recompiled it and restarted gdb? Have you seen any warnings similar to "executable is more recent than source"?
If I re-run the program, even if I set the break point at the
beginning of the main() it still get segmentation fault, it means the
program is running within the library file
Actually it means that you either failed to set breakpoint on main function or program execution not reaches main and gets segmentation fault. Try the following steps:
Rebuild program from scratch with debug info (-g gcc option). Reset breakpoint and watch for any warnings from gdb.
If program still crashes with breakpoint set on main look at stack trace (bt command in gdb). It is probably happening before main and you will not see main in stack trace.

Sending commands to gdb from the debugged program

Is it possible to control gdb from the debugged program? I'm hoping for a library that can help with this, ideally with an API such as gdb_sendcmd("bt"), but I can live with something like connecting to local gdb via a socket.
Primary use case is programmatically adding a data breakpoint to monitor when a certain memory address next gets modified. Target language is, naturally, C; anything applicable to it can be reused with C++ and Objective-C.
Answer from Employed Russian has solved my direct problem, but I'd still love to know how I can run GDB commands programmatically from the debugged program. It may speed up some debugging if I could simply add code to the project instead of writing extra startup commands for GDB that would create breakpoints with attached commands.
So if there is a way to run commands programmatically, I'd still love to hear it ;)
The Python interface exported by GDB allows you to do many things. Maybe something like this would fit your requirements:
import gdb
CMD_FCT = "gdb_run"
CMD_NAME = "str"
class GdbRunBreakpoint(gdb.Breakpoint):
def __init__(self):
gdb.Breakpoint.__init__(self, CMD_FCT, internal=1)
self.silent = True
def stop(self):
cmd = gdb.parse_and_eval(CMD_NAME).string()
gdb.execute(cmd)
return False
GdbRunBreakpoint()
(just write than in a file, and source it from your .gdbinit file)
and on the application side:
void gdb_run(char *str) {}
int main () {
gdb_run("where");
}
I think the code is straight forward, but as I mentioned in https://stackoverflow.com/a/8884512/341106, not everything is allowed in the stop callback, GDB is in an intermediate state, but many things will work as expected.
EDIT: needless to say, this won't work if you app is not compiled with debug symbols!
Is it possible to control gdb from the debugged program?
No. If the program could do that, and (say) disabled all breakpoints, how would you debug it?
Primary use case is programmatically adding a data breakpoint to monitor when a certain memory address next gets modified.
This often comes up in a context like this: on Nth invocation of foo(), a (local or global) variable bar gets unexpectedly clobbered, and you want to find the culprit.
If that is indeed your problem, then set a breakpoint on the line where you know the value of bar is still good (just after it has been initialized). Set ignore count (using ignore command) on that breakpoint to N-1, and then, when the breakpoint is hit, set the watchpoint on bar.
You can even attach commands to the breakpoint:
commands 1 # assuming this was the first breakpoint
watch bar
continue
end
so the watchpoint is attached automatically.

GDB: Is there a command that allows you to see how many times a function has been called?

I am currently having to write implementations of malloc() and free(), and am given a driver program that will run my two implementations.
But currently, I am segfaulting because free() is trying to free a payload size that is well in the billions of bytes (which is wrong). I have the line and line number from running GDB, but I need to know if malloc() and free() have been called more than once, to confirm that there is indeed at least one case where it runs smoothly.
First set a breakpoint for malloc and free. Afterwards use the "ignore" command with a high value to suppress really stopping at those breakpoints. GDB will still count how many times the breakpoints have been hit. When you call "info breakpoints", GDB will show you these counts.
Just to complete the information of Martin, run gdb and then, on the gdb prompt:
b <file:line_number or function name>
ignore <breakpoint identifier> 100000
Then you run your executable (or you resume) and then, when you want to check the number of times the breakpoint has been hit, on the gdb prompt:
info breakpoints
This is a good use case for a conditional breakpoint, where you can filter out calls that exceed your size threshold. Use the if (condition) clause in break.
Another option on linux is to use perf to set a probe and capture arguments. See perf probe for details. This lets you instrument the binary non-intrusively and trace all calls. perf script is good for outputting the results.
(gdb) help break
Set breakpoint at specified line or function.
break [LOCATION] [thread THREADNUM] [if CONDITION]
LOCATION may be a line number, function name, or "*" and an address.
If a line number is specified, break at start of code for that line.
If a function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no LOCATION, uses current execution address of selected stack frame.
This is useful for breaking on return to a stack frame.

Stepping into swapcontext() with gdb

I'm doing a project that makes unix system calls. To be specific, my project heavily relies of calls to getcontext(), makecontext(), swapcontext() and setcontext(). I tried to debug my code using gdb. I stepped into the code line by line and examined the control but once a call to swapcontext() is made, it doesn't step into the code anymore. Instead, debugging almost stops there and the rest of the program is run automatically instead of line by line. I guess gdb does not go into context calls? Is there any way to get around this? Is there a debugger that i can use for this?
Thanks
setcontext and swapcontext calls change the program's stack, and gdb gets confused. I do not know whether some other debugger can handle it nicely.
gdb steps through one thread and calls this the current thread. Other threads will run as you are doing this. If you set a breakpoint that gets hit in a thread other than the current thread then gdb will change the current thread to that thread. Stepping is now relative to the new current thread.
Stepping with gdb over calls of swapcontext() with 'step' or 'next' does not work because not only the stackpointer changes but also the call returns to a different code line (which is the desired effect of swapcontext()). As gdb puts a breakpoint in the next code line which will not be executed until another swapcontext() returns to this place the execution will not break.
You need to foresee the line to which swapcontext() will return and set a breakpoint there. For a new (unused) context this will be the line you specified as entry function. For used contexts it will probably one of the lines after a swapcontext() there...
You can repeatedly use GDB's stepi command to first step into and then step through the swapcontext() function. You must step several dozen times, including a few steps over kernel system calls—I presume to save the floating point state?—and you'll eventually come out in the user thread you're swapping to. It's a tad time-consuming, but it works.
As much as you may not like this answer, the best bet is to step through your code in small chunks by hand. Threaded programs don't play very well with debuggers like GDB and Valgrind (at least in my experience) and most bugs can be determined by a careful step-by-step manual analysis of the code.

Resources