When debuging a simple program in gdb, I want to continue the execution automatically after hitting breakpoints. As far as I know, there are two methods to accomplish it:
1) use hook-stop.
define hook-stop
continue
end
But it seems the hook-stop is trigged only once. When another breakpoint is hit next time, the execution still stops.
2) use gdb.events.stop.connect().
def handle_stop_event(event):
if isinstance(event, gdb.BreakpointEvent):
gdb.execute('continue')
gdb.events.stop.connect(handle_stop_event)
This method works well. But if there are too many breakpoints been hit, an error "Fatal Python error: Cannot recover from stack overflow." occurs.
It seems because of recursive call. I'm wondering why the gdb.execute('continue') would cause this issue.
I searched online and still didn't find a solution.
PS: gdb version 7.11.1 on Ubuntu 16.04
Any advice would be appreciate! Thanks in advance.
It seems, continue inside hook-stop doesn't work properly. Have you seen this question I posted yesterday?
I think, the best approach here is writing a convenience function in python and setting a conditional breakpoint. Or using commands — see the "Breakpoint Command Lists" section of the GDB user manual.
Here's how do to it (also described in the manual).
The python module:
import gdb
class should_skip_f(gdb.Function):
def __init__ (self):
super (should_skip_f, self).__init__("should_skip")
def invoke(self):
return True # Your condition here
should_skip_f()
(gdb) b <your target> if !$should_skip()
Or add the condition to existing breakpoints with
(gdb) condition <BNUM> !$should_skip()
The only downside is that you have to set the condition for each breakpoint individually, but that's scriptable. Also, I think, the commands syntax allows you to add commands to a list of breakpoints at once.
'commands [LIST...]'
'... COMMAND-LIST ...'
'end'
Specify a list of commands for the given breakpoints. The commands
themselves appear on the following lines. Type a line containing
just 'end' to terminate the commands.
As for the recursion — yeah, that's a bad "design" of a debugger script (if one should talk about design of one-off throwaway things). You can examine what happens there if you extend your python script like so
import inspect
...
def handle_stop_event(event):
...
print(len(inspect.stack())) # Or you can print the frames themselves...
The Python interpreter doesn't know that execution does not return from gdb.execute("continue"), so the Python stack frames for invocations of this function are never destroyed.
You can increase max stack size for the interpreter, but like I said, this script does not seem like the best solution to me.
Is there a way to do this - not with just getting the last things that were in esp/rsp because when I use that in my program I also get the variables that were there but now there are not here. Thanks!
Use the command backtrace full (or abbreviate to bt full) to get all the local variables from parent frames too.
I have run into a core and cannot get the traceback from it. I have two questions.
Can I find out the line which causes the crash or where the crash occurred from the
list command output?
How to deal with it otherwise. What should I set heuristic-fence-post to to get some
meaningful data. I tried setting it to 0 but no luck.
(gdb) bt
0 0x00e67a24 in ?? ()
warning: GDB can't find the start of the function at 0xe67a24.
GDB is unable to find the start of the function at 0xe67a24
and thus can't determine the size of that function's stack frame.
This means that GDB may be unable to access that stack frame, or
the frames below it.
This problem is most likely caused by an invalid program counter or
stack pointer.
However, if you think GDB should simply search farther back
from 0xe67a24 for code which looks like the beginning of a
function, you can increase the range of the search using the `set
heuristic-fence-post' command.
(gdb)
A workaround that often works when I see this problem is the command:
x/100a $sp
This will dump the stack with symbols and it's likely that at recent parts of the backtrace will be there. It still won't find the actual current stackframe, but should find the most recent ones with symbols.
Depending upon the target architecture, $sp may need to be something else - whatever register is the stack pointer.
The most common case for me to see gdb fail to find the call stack is for a crash in OpenGL drivers which do not use the expected ARM ABI calling conventions.
I ran into this same error and it turned out to be a symptom of a different problem: I didn't provide a file to gdb, which therefore couldn't build a symbol table. Starting it via gdb filename instead of just gdb fixed this as well.
I'm writing a GDB script to walk the stack and inspect certain local variables only if the function running at that stack level is a specific one. How can I programatically check which function is running at each level? "backtrace" shows what I want. I just need it in a variable.
You can do what you want in GDB 7.3, which has Python scripting and exposed stack frame info to the Python interpreter.
I decided to find out how our C/C+ *nix practitioners use the gdb debugger.
Here is what I typically use:
b - break filename.c:line #, function, filename.cpp:function, className::Member
n, c, s -- next continue step
gdb program name => set breakpoints ==> run [parameter list] (I do this to set break points before the program starts)
l - to list the surrounding source code.
attach processID
6 break [location]
gdb programName corefile.core (to examine why app crashed)
I also sometimes set breakpoint at exit function (break exit) to examine program stacks
info b to examine all the breakpoints
clear [breakpoints list ]
How do you use it?
Besides things that have already been posted i also use:
a .gdbinit file for STL containers
signal SIGNAL noprint nostop for some custom signals that are of no real interest when debugging
C-Casts to dereference pointers
catchpoints (catch throw, catch catch)
condition for conditional break- and watchpoints
rarely gdbserver for remote debugging
gdb program coredump, for those embarassing segfaults ;)
PS: One reason i personally love gdb btw. is that it supports tab-completion for nearly everything (gdb commands, symbols in the symbol table, functions, memberfunctions etc.). This is a fairly good productivity boost in my opinion.
Scripting is a nice GDB feature.
First you set a breakpoint, like: b someFunction\n.
Then you run command: commands\n. GDB will ask for commands for that breakpoint.
Common scenario is to print some value and then continue, so you will enter: p someVar\n continue\n.
To end the script press: Ctrl-D
After running program you will see your script executed occasionally when the breakpoint occurs.
Most useful gdb commands in my opinion (aside from all already listed):
info threads - information about threads
thread N - switch to thread N
catch throw - break on any thrown exception. Useful when you caught the bug only after the stack unwound.
printf,print - examine any and all expressions, printf accepts C-style formatting specifiers
Finally, if debugging over a slow link, the text UI might be of use. To use it, start gdb with the --tui command-line switch.
gdb is not my speciality, but here is what i use:
bt list a stack
up, down moving in a stack
until continue until a line with greater number than current is reached -- for exiting loops
watch [expr] break the program when expr changes
... but mostly i use ddd as a frontend to gdb
Type Ctrl-X Ctrl-A to open a simple window with source preview.
Some time ago I found cgdb:
http://cgdb.sourceforge.net/
This is a curses (color console) based frontend for gdb that made my life a lot happier when I was restricted to debugging in a console window.
See the user guide at http://sources.redhat.com/gdb/current/onlinedocs/gdb_toc.html.
There are also a couple of uses that are not directly connected with debugging. For example it
can be used for C expression evaluation:
(gdb) printf "%lu\n", (unsigned long)(-3L)
4294967293
i use the gdb -tui switch for a great 'text user interface' (a kind of gui in text mode). It supports multiple windows and is generally much more friendly than using the 'list' command (since it shows the source in a sep window)
Beginners using gdb will feel it as tough. But there GUI based tool DDD(Data Display Debugger) which is same as gdb. u have a console in the bottom to run gdb commands and top 3/4th portion would be the code. U ll have the option to learn and understand the commands and the flow excatly