GDB - show last n lines executed - c

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).

Related

How does gdb implement call function

When I use gdb to debug process in arm linux I can use call like call write(123,"abc",3)
How does gdb inject that call into process and recover all?
How does gdb inject that call into process and recover all?
GDB can read and write the inferior (being debugged) process memory using ptrace system call.
So it reads and saves in its own memory some chunk of instructions from inferior (say 100 bytes).
Then it overwrites this chunk with new instructions, which look something like:
r0 = 123
r1 = pointer to "abc"
r2 = 3
BLR write
BKPT
Now GDB saves the current inferior registers, sets ip to point to the chunk of instructions it just wrote, and resumes the inferior.
Inferior executes instructions until it reaches the breakpoint, at which point GDB regains control. It can now look at the return register to know what write returned and print it. GDB now restores the original instructions and original register values, and we are back as if nothing happened.
P.S. This is a general description of how "call function in inferior" works; I do not claim that this is exactly how it works.
There are also complications: if write calls back into the code that GDB overwrote, it wouldn't work. So in reality GDB uses some other mechanism to obtain suitable "scratch area" in the inferior. Also, the "abc" string requires scratch area as well.

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.

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.

GDB structure output

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

Resources