If You Have Hit a Breakpoint in Gdb
Kernighan famously said:
Anybody knows that debugging is twice as difficult as writing a program in the first identify. So if you're as clever as you can be when you write information technology, how will you e'er debug information technology?
On the surface, this is a phone call to go along your code simple, but there is a corollary: debuggability is the limiting factor in software development. Any your metric for the "goodness" of your software - performance, features, size, velocity - if you double your effectiveness at debugging yous'll double the "goodness" of your software.
Over the final year or so, I shared on the gdbWatchPoint resources center numerous means to aid y'all increase the pace of your debugging.
In this article, I choice five of my favorite GDB topics that I believe tin can help you spend fewer hours debugging and write amend software faster.
Let's dive in.
1. GDB TUI Fashion
GDB'south control-line isn't intuitive, but if you spent some fourth dimension discovering and learning the commands, then you'll notice it very powerful.
I approximate, ane of the least known, but maybe the near useful things in GDB is TUI mode, i.e. Text User Interface mode.
The trouble with the GDB command-line is that information technology doesn't requite you the context of where you are in the programme; for example, if the programme hits a breakpoint, and then GDB returns you lot but ane line.
If you blazon Ctrl-ten-a
(or tui enable
), then another text window opens; the source window shows the source file of the program, besides as the current line and the breakpoints. You're now in GDB'southward TUI mode.
Information technology'due south not all sunshine though. Sometimes the screen messes upward a fleck just Ctrl-l
refreshes the screen.
It'southward unlikely that the source window lonely provides you with all the information you lot demand. Typing Ctrl-ten-2
helps you bike through different text windows and layouts:
- source window only,
- assembly window just,
- dissever-view with source and assembly,
- split-view with source and registers, or
- carve up-view assembly and registers.
These windows are non all visible at the same time. The command window with the GDB prompt and GDB output is ever visible.
Ctrl-x-1
returns the layout to the command window with the source or associates pane.
Finally, you lot'll notice that the pointer-keys scroll the active window in TUI mode, which means that you can't use the upward and down arrows to become to your previous commands as you lot normally would do in the GDB command-line. To motion through your control history, employ Ctrl-p
(previous command) and Ctrl-north
(next command) instead; Ctrl-b
and Crtl-f
respectively to movement the cursor back (left) and frontward (right) to edit the line.
UDB Time Travel Debugger
Find and gear up test failures in minutes - including C/C++ race conditions and retention corruptions
Acquire more »
2. GDB Breakpoint Types
A breakpoint lets you terminate the execution of the program at a time of your choice. Information technology's an essential (and I reckon probably the virtually used) command in your debugging period.
In that location are different breakpoint types.
Basic breakpoints
Y'all set a bones breakpoint with the post-obit command:
break [LOCATION]
or merely b [LOCATION]
Where LOCATION
can exist a line number, function name, or "*" and an address.
(gdb) break hello.c:vii
In one case your programme hits a breakpoint, it waits for instruction. You tin can navigate or pace through the programme using side by side
, continue
, step i
, and other commands. To speed up your typing, you lot tin can abbreviate all of these commands; northward
for side by side, c
for continue, si
for step i - you get it.
Temporary breakpoints
A temporary breakpoint only stops the execution of the program one time. When the program hits a temporary breakpoint, information technology deletes automatically, which saves you the trouble of managing and cleaning up obsolete breakpoints.
You ready a temporary breakpoint with the following control:
tbreak [LOCATION]
(gdb) tbreak main
Tip: Using the start
command instead of the usual run
command sets a temporary breakpoint atmain()
.
Conditional breakpoints
Instead of stepping through the execution of the program until it hits the breakpoint again, you can specify a status for a breakpoint that stops the execution if met. You can write pretty much any condition yous desire in the programming language of the program that you're debugging, which makes conditional breakpoints very powerful and efficient.
Yous set a conditional breakpoint with the following command:
break [LOCATION] if [Condition]
Here [CONDITION]
is a boolean expression, which, in GDB, is TRUE
if the result is nonzero; otherwise, information technology is FALSE
. The condition tin include a function call, the value of a variable, or the result of any GDB expression.
(gdb) break my_func if i==5
You lot can make all breakpoint types conditional by adding the suffix, if [Condition]
.
In that location is more you lot can do. You can gear up a condition on an existing breakpoint by using the breakpoint number as a reference.
condition [BREAKPOINT #] [CONDITION]
(gdb) condition 2 i==five
Typing condition [BREAKPOINT #]
removes the condition from a breakpoint.
REGEX breakpoints
The regex breakpoint command sets an unconditional breakpoint on all functions that lucifer a regular expression (regex) and prints a list of all breakpoints it set. Once gear up, these breakpoints are treated only like the breakpoints you gear up with the normal break control. You tin delete them, disable them, or brand them conditional the same way equally whatsoever other breakpoint.
You set a regex breakpoint with the following command:
rbreak REGEXP
(gdb) rbreak hello.c::my_func*
When debugging C++ programs, rbreak
is peculiarly useful for setting breakpoints on overloaded functions that are non members of whatever special classes.
rbreak
saves you a lot of time typing and trying to remember exact role names.
In this recording, I embrace the various breakpoint types, and how to use each of them in your debugging.
3. GDB'due south tight integration with Python
GDB has tight integration with Python. You tin do all kinds of smart things to help make detecting (and resolving) thorny bugs a breeze. Plus, in that location are lots of other tricks you can do to customize GDB to your particular project and debugging needs - for example, scripting routine actions, writing your own commands, and creating pretty-printers.
Not taking reward of Python is something y'all may regret later, a missed opportunity to increase your debugging speed. Information technology's a pocket-sized investment in time that pays back speedily and, over fourth dimension, significantly.
You can start pocket-sized and aggrandize your Python resources over time.
A elementary way to go started is past invoking the interpreter with typing python
. You can now use any Python lawmaking, for example, typing print('Hello Earth')
, followed by typing end
calls the python print()
office.
The Python code isn't passed to another process but runs inside the GDB process. Python truly integrates with GDB.
Simply to use the Python in GDB properly, you lot must import the GDB module, which gives you all you lot need.
(gdb) python import gdb
Switching to TUI manner, yous can use the .execute
command to create a breakpoint, or even better, create an object example of gdb.breakpoint
. We at present can dispense and interrogate this object, enable or disable it, etc.
Pretty much anything you tin can practice on the GDB command-line y'all tin do with a breakpoint from Python. Y'all can append commands to a breakpoint, get in conditional, or make the breakpoint specific to a thread.
The aforementioned is true for most other commands in GDB; if y'all tin do it from the GDB command-line, and then yous tin can practise information technology from Python.
Tip: Consider making a gdbinit
per project, and committing it into your project'south source control and then that everyone working on that project can benefit.
In this video, I dip into the Python integration with GDB to become you started. If you lot've struggled with imagining what Python can do, this one helps you out.
4. GDB Pretty-Printers
Nosotros all use structures and classes in the code we write, and GDB endeavors to brandish what these are but misses the contextual information; when you apply a handful of members, and in particular unions, then interpreting these more than complicated structures can go overwhelming.
When GDB prints a value, it checks whether there is a pretty-printer registered for that value first. If there is, and so GDB uses that pretty-printer to brandish the value. Otherwise, the value prints in the usual fashion.
In the instance below, I didn't have a pretty-printer for the siginfo_t
structure, which acquired the print info control to return all the data in the construction, including expanding the unions it uses.
What do you think?
Messy and non like shooting fish in a barrel to read.
I promise, creating a simple pretty-printer saves you much time staring at your computer screen.
Most pretty-printers contain of two main elements:
- The lookup function to identify the value type, and
- the printer function itself.
To see how this works, permit's write a basic pretty-printer in Python that returns the si_signo
value from the siginfo_t
structure for an interrupt bespeak that the plan receives.
# Start off with defining the printer equally a Python object.class SiginfoPrinter:
# The constructor takes the value and stores it for later on.
def _init_(cocky, val):
self.val = val# The to_string method returns the value of the
# si_signo attribute of the directory.def to_string(self):
signo = cocky.val['si_signo']
render str(signo)# Adjacent, define the lookup office that returns the
# printer object when it receives a siginfo_t.# The function takes the GDB value-type, which, in
# our example is used to await for the siginfo_t.def my_pp_func(val):
if str(val.type)=='siginfo_t': return SiginfoPrinter(val)# Finally, append the pretty-printer as object/ function to
# the listing of registered GDB printers.gdb.pretty_printers.append(my_pp_func)
# Our pretty-printer is now bachelor when we debug
# the inferior programme in GDB.
Now, run whatsoever plan and hit Ctrl-c
to quit. The pretty-printer returns the value 2; the value for a SIGINT
.
(gdb) source prettyprint.py
(gdb) print info
$four = 2
(gdb)
Much easier to read.
Of class, this is just a unproblematic pretty-printer program, simply the possibilities are endless. You tin excerpt and print any value of a fellow member in a structure with your pretty-printer.
In my video, I show y'all a quick way to pretty-impress structures in GDB and build-out this basic pretty-printer some more than. Y'all'll learn that it isn't difficult to extrapolate this handy printer to brandish whatever structure you desire.
5. Reversible Debugging
To quote Kernighan once more:
Debugging involves backward reasoning, like solving murder mysteries. Something impossible occurred, and the only solid data is that it really did occur. So we must recollect astern from the result to discover the reasons.
Or in other words, we actually desire the debugger to be able to tell us what happened in the past - reality has diverged from your expectations, and debugging ways figuring out at what point your expectations and reality diverged.
You demand to know what your program actually did as opposed to what you expected it was going to do. This is why debugging typically involves reproducing the problems many times, slowly teasing out more and more information until you pivot it down.
Reversible debugging takes away all that guesswork and trial and error; the debugger tin can tell you straight what just happened.
Not everyone knows about it, simply GDB has congenital-in reversible debugging since release vii.0 (2009). It works pretty well, just you've to be ready to sacrifice performance (a lot of it); information technology's dramatically slower than any of the purpose-congenital fourth dimension-travel debuggers out in that location similar UDB.
Simply information technology's built right in, so why not utilise information technology?
Type record
to start reversible-debugging.
(gdb) record
You can use reverse commands to go backward, for instance:
reverse-next (rn)
- pace the program backward, run through subroutine calls
reverse-nexti
(rni)
- footstep astern ane education, only run through chosen subroutines
reverse-footstep
(rs)
- step the program backward until it reaches the beginning of a previous source line
opposite-pace
(rsi)
- step backward i instruction
reverse-continue
(rc)
- continue the program but run it in reverse
reverse-finish
(rf)
- execute the program backward until but before the indicate the retentiveness changes
The challenge is that in well-nigh cases, you tin't predict when the programme faults, which means that y'all may have to run (and record) the plan repeatedly until it eventually stalls.
Some GDB commands can aid you out hither.
Breakpoints and watchpoints work in reverse, which can help you, for example, to go on straight to a previous indicate in the program at which specific variable changes. Reverse watchpoints tin be incredibly powerful. I know of several instances of bugs that alluded a programmer for months or even years that were solved in a few hours with the power of reverse watchpoints.
Another absurd GDB thing is that you can trigger a command (or series of commands) when the program hits a breakpoint.
Type command [breakpoint #]
, where [breakpoint #]
is the identifier for your breakpoint.
command 1
Blazon commands for breakpoint(south) 1, one per line.
End with a line proverb merely "terminate".
tape
continue
end
In this video, I demonstrate live on stage reversible-debugging in GDB. Check information technology out, it shows you step-by-step (in reverse) how to trace a fault in my programme.
Effort UDB for free
Step backwards in time in your programme to view registers and retentivity with a Fourth dimension Travel Debugger
Learn more »
That'southward it.
I shared five piece of cake ways to reduce your debugging hours. Perhaps a little overwhelming now, but the skillful news is that you don't have to adopt all at once. That probably would accept the opposite effect. Sometimes little tweaks to your usual debugging habits and routines can already brand a large difference. Just showtime with small-scale steps.
Accept your time to read the dissimilar tutorials and lookout man the videos that I shared in this commodity and adopt the things that you feel can amend your debugging. And, brand sure to share your takeaways with your project members and organization and then everyone benefits.
To make sure you exercise not miss my next GDB tutorial, sign up for the gdbWatchPoint mailing now.
gilbreaththishent.blogspot.com
Source: https://undo.io/resources/gdb-watchpoint/5-ways-reduce-debugging-hours/
0 Response to "If You Have Hit a Breakpoint in Gdb"
Post a Comment