I'm currently debugging syslinux (a boot loader) through the gdb stub of qemu.
Recently, I wrote some gdb commands that (un)load the debug symbols everytime a module is dynamically (un)loaded. In order not to disrupt the execution, I ended the commands with continue.
break com32/lib/sys/module/elf_module.c:282
commands
silent
python
name = gdb.parse_and_eval("module->name").string()
addr = int(str(gdb.parse_and_eval("module->base_addr")), 0)
gdb.execute("load-syslinux-module %s 0x%08x" % (name, addr))
end
continue
end
However, when stepping through the code line by line, if the next or step command makes the execution hit the breakpoint, the breakpoints takes precedence, the commands are executed, including the continue. And the execution continue irrespectively of the line-by-line debugging I was doign. This also happen if I try to step over the function that has this breakpoint.
How can I keep (un)loading the debug symbols on the fly while not interfering with the debugging?
Is there an alternative to the continue command? Maybe using breakpoints isn't the right way? I'd take any solution.
This can't be done from the gdb CLI. However, it is easy to do from Python.
In Python the simplest way is to define one's own gdb.Breakpoint subclass, and define the stop method on it. This method can do the work you like, then return False to tell gdb to continue.
The stop facility was designed to avoid the problems with cont in commands. See the documentation for more details.
Related
I'd like to to debug a multiprocess C++ project with GDB, specifically I'd like to know if there is a way to achieve the following
Attach multiple processes to a single instance of GDB while letting all the processes run
Setting up a breakpoint in the source code of one of the processes stops all the attached processes
The ideal solution would be something similar to what is offered by the Visual Studio debugger as described here.
At the moment I'm able to attach multiple processes to a GDB instance but then only the current selected inferior is executed while the others are stopped and waiting for a continue command.
In order to be able to run inferiors in the background, one needs to issue this gdb command
set target-async on
after start up and before running anything. With this option in effect, one ca issue
continue&
(or just c&) and this will send the inferior to the background, giving an opportunity to switch to run another one.
Stopping all inferiors at once is a bit more difficult. There is no built-in command for that. Fortunately gdb is scriptable and it is possible to attach a script to a breakpoint. Once the breakpoint is hit, the commands are executed. Put inferior n and interrupt commands in the script for each inferior. It is probably more convenient to do that from a Python script, something like
(gdb) python
>inf = gdb.inferiors()
>for i in inf:
> gdb.execute("inferior %d" % i.num)
> gdb.execute("interrupt")
Some debuggers (like pdb) automatically break at your first line of code, then allow you to add breakpoints as needed. I'd really like to have that functionality with gdb. (I need to trace code execution through a huge codebase, and none of my guesses as to where to set a breakpoint have been correct, so the program just runs through to the end.) I've read that you can get similar functionality with gdb's starti command, but gdb takes it a little too literally: it stops on the VERY first line of the program where the linking information is. How can I move past this and actually step into my program? I've tried running the s command, but nothing looks familiar.
Here's a picture of what I see when I run starti.
Use start, not starti. start puts a temporary breakpoint on your main() function and begins executing. It should start at the beginning of your program proper.
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.
I know the answer to this, I'm putting it up here for others to see it
If you use eclipse CDT, you probably understand that eclipse isn't a debugger, it's just an application front-end, specifically to GDB. So when debugging C++ programs, you're actually just using GDB in a more comfortable manner. If you ever have to debug a multithreaded program in eclipse CDT, you'll realize that things quickly get hectic because when you hit a breakpoint, all threads stop, and when one tries to execute a single line in a specific thread, it also runs the other threads. In order for it to work properly, the threads have to be able to be run arbitrarily and exlusively-so that when the programmer executes a single line, it only executes the specific thread.
So, by default, gdb's settings by default leave the "scheduler-locking" turned off. If you debug multithreaded applications you'll understand that this must be on in GDB in order for the desired behavior to be achieved. How does one run this command:
set scheduler-locking on
in GDB within eclipse CDT?
At least one way to do it that certainly solves the problem is knowing how to navigate the immense set of features that eclipse offers. Typically, when a program starts, eclipse CDT switches the console window (if you have it open, typically it's on the bottom) to show the input/output of the program.
But you can change this if you didn't know-see this image. That button on the second to last right-the blue one that looks like a monitor-you can select the GDB input console. It was discussed also in this thread.
From there merely type the command.
SOLVED, BUT NEED A BETTER SOLUTION
But now that this has been solved, to solve it in a better way as a matter of convience; having to type set scheduler-locking on every time a program starts is silly. But the problem with loading a gdbinit file is that the gdbinit file gets sourced before eclipse has set the program for gdb to solve. This is a problem, as it causes the debugger view to hang within eclipse, as gdb complains. To understand what is happening, try and fire up gdb, then give the command without loading a binary to execute. It fails-so how does one set this as an option that is sticky?
Maybe if you add the following gdb script which could set the variable when the program stops and turns it off if you continue:
define hook-step
set scheduler-locking on
end
define hookpost-step
set scheduler-locking off
end
define hook-run
set scheduler-locking off
end
define hook-continue
set scheduler-locking off
end
My answer is derived from the one by #user1448557 . Unfortunately, I don't currently have enough reputation to comment on it (or to upvote it by the way). The strategy seems great, but the answer might be a bit outdated because it doesn't involve "set scheduler-locking step". I have put the following in my gdb initialization file (within my Eclipse project) and it does what I want.
#inspired from [link to this thread][1]
define hookpost-run
set scheduler-locking step
end
With regards to the comment by #rbaleksandar, Eclipse CDT launch configurations allow one to specify a "GDB Command File" and the default is usually .gdbinit
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