Gdb
This Tutorial is taken from here
- GDB Holdings Bhd. Operates as an investment company, which engages in the provision of construction services. It focuses on high rise residential, commercial, and mixed development projects. The company was founded on February 28, 2013 and is headquartered in Puchong, Malaysia.
- Jan 24, 2011 Despite its age, gdb remains an amazingly versatile and flexible tool, and mastering it can save you huge amounts of time when trying to debug problems in your code. In this post, I'll share 10 tips and tricks for using GDB to debug most efficiently. I'll be using the Linux kernel for examples throu.
In this article, let us discuss how to debug a c program using gdb debugger in 6 simple steps.
Write a sample C program with errors for debugging purpose
To learn C program debugging, let us create the following C program that calculates and prints the factorial of a number. However this C program contains some errors in it for our debugging purpose.
% gdb broken This only starts the debugger; it does not start running the program in the debugger. Look at the source code and set a breakpoint at line 43 (gdb) b 43 which is double seriesValue = ComputeSeriesValue(x, n); Now, we start to run the program in the debugger.
Let us debug it while reviewing the most useful commands in gdb.
Step 1. Compile the C program with debugging option -g
Compile your C program with -g option. This allows the compiler to collect the debugging information.
Note: The above command creates a.out file which will be used for debugging as shown below.
Step 2. Launch gdb
Launch the C debugger (gdb) as shown below.
Step 3. Set up a break point inside C program
Other formats:
- break [file_name]:line_number
- break [file_name]:func_name
Places break point in the C program, where you suspect errors. While executing the program, the debugger will stop at the break point, and gives you the prompt to debug.
So before starting up the program, let us place the following break point in our program.
Step 4. Execute the C program in gdb debugger
You can start running the program using the run command in the gdb debugger. You can also give command line arguments to the program via run args. The example program we used here does not requires any command line arguments so let us give run, and start the program execution.
Once you executed the C program, it would execute until the first break point, and give you the prompt for debugging.
You can use various gdb commands to debug the C program as explained in the sections below.
Step 5. Printing the variable values inside gdb debugger
As you see above, in the factorial.c, we have not initialized the variable j. So, it gets garbage value resulting in a big numbers as factorial values.
Fix this issue by initializing variable j with 1, compile the C program and execute it again.
Even after this fix there seems to be some problem in the factorial.c program, as it still gives wrong factorial value.
So, place the break point in 10th line, and continue as explained in the next section.
Step 6. Continue, stepping over and in – gdb commands
There are three kind of gdb operations you can choose when the program stops at a break point. They are continuing until the next break point, stepping in, or stepping over the next program lines.
- c or continue: Debugger will continue executing until the next break point.
- n or next: Debugger will execute the next line as single instruction.
- s or step: Same as next, but does not treats function as a single instruction, instead goes into the function and executes it line by line.
By continuing or stepping through you could have found that the issue is because we have not used the <= in the ‘for loop’ condition checking. So changing that from < to <= will solve the issue.
gdb command shortcuts
Use following shortcuts for most of the frequent gdb operations.
- l – list
- p – print
- c – continue
- s – step
- ENTER: pressing enter key would execute the previously executed command again.
Miscellaneous gdb commands
- l command: Use gdb command l or list to print the source code in the debug mode. Use l line-number to view a specific line number (or) l function to view a specific function.
- bt: backtrack – Print backtrace of all stack frames, or innermost COUNT frames.
- help – View help for a particular gdb topic — help TOPICNAME.
- quit – Exit from the gdb debugger.
Contents:
About gdb and dddGetting Started with gdb
Common Comands
the info command for getting application and debugger state
Setting conditional breakpoints and setting breakpoints in C++ methods
Keyboard shortcuts in gdb
invoking make in gdb
Advanced features debugging threaded programs, attaching to an already running process, debugging a child process after a fork, signal handling
Assembly code debugging (using gdb to debug at the assembly code level, and how to examine memory and register values)
Links to more gdb information
Some settings (and bug fixes) for ddd
Here are some of the usful actions that gdb can perform:
- Start your program and step through it line by line
- Make your program stop on specified conditions
- Show the values of variables used by your program
- Examine the contents of any frame on the call stack
- Set breakpoints that will stop your program when it reaches a certain point. Then you can step through part of the execution using step and next, and type continue to resume regular execution.
For C and C++ programs, gdb and ddd are debuggers that you can use. ddd
is a easy-to-use GUI wrapper around an inferior debugger (gdbfor GNU compiled C or C++ code). ddd
allows you to interactwith the debugger by using either GUI menu options or the under-lying debugger's command line interface. In addition, ddd
automatically displays source code when breakpoints are reached.
There are some example programs and some documentation on using gdbto debug them that you can copy from here: /home/newhall/public/gdb_examples/
-g
option can be debugged using GNU's debugger gdb
(actually, youcan use gdb on code that is not compiled with -g, but unless you like trying tofigure out how assembly code sequences map to your source code I wouldn'trecommend doing so). Also, do not compile with an optimization flag (i.e.don't use -O2), or gdb will have a hard time mapping optimized machine codeto your source code. For example:To start gdb, invoke gdb on the executable file. For example:If your program terminates with an error, then the operating system willoften dump a core file that contains information about the state of theprogram when it crashed. gdb can be used to examine the contents of a corefile:One good way to get started when you are trying to track down a bug, is to set breakpoints at the start of every function. In this way, you will quickly be able to determine which function has the problem. Then you can restart the program and step through the offending function line-by-line until you locate the problem exactly.
ddd is invoked in a similar way:
gdb also understands abreviations of commands, so you can just type up to the unique part of a command name ('cont' for 'continue', or 'p' for 'print', 'n' for next, 's' for step, ...)
- help help documentation for topics and gdb commands
- break
- run Starts program running from the beginning
- continue Continues execution from breakpoint
- step (or s) Executes next line(s) of program
- next (or n) Like step, but treats a function call as a single instruction
- until <line> Executes program until line number <line>
- quit Quits gdb
- list lists program source code
- where (or backtrack or bt) Shows stack: sequence of function calls executed so far
good for pinpointing location of a program crash - frame Shows all stack frames
- info break Shows current breakpointsSee the info command section for lots of other uses of the info command.
- enable, disable, delete/clear: enable, disable, or delete one or more breakpoints
- condition conditional breakpoints: set conditions on breakpoints
- print Display program values, results of expressions To represent different formats in the expression (the default is decimal):You can use register values and values stored in memory locations in expressions:
- x (Examine Memory): display contents of the memory location (like print, but prints out what is stored at the address listed as its argument)Can display in diffent formats (as an int, a char, a string, ...), and the format is sticky: specify the format once to set it and subsequent x command use it.
In general x takes up to three arguments (x/nfu memory_address), theorder does not matter:
- n: the repeat count (a postitive integer value)
- f: the display format (s:string, i:instruction, x:hex, d:decimal, t:binary, a:address, ...)
- u: the units format (number of bytes) (b:byte, h:2bytes, w: 4bytes, g:8bytes)
- display Automatically display value of expression each time abreakpoint is hit
- whatis List type of an expression
- info get information about a whole lot of things
- set chage values of variables, memory, registers
Here are some gdb commands that are useful for debugging at the assembly code level (the Common Comands section has moregeneral details about some of these commands, particularly formatting options for print and x):
Quick summary of common commands for assembly debugging
Here is some more information about assembly-level debugging in gdb, including a simple example session:Debugging IA32 Assembly Code with gdb (and ddd)Below is output from two runs of gdb on programs from ~newhall/public/gdb_examples/.
- Run 1 is a gdb run of badprog.c. It demonstrates some common gdb commands, and it finds one of the bugs in this program...there are others.
- Run 2 is a gdb run of segfaulter.c. It demonstrates how to find out where your program is segfaulting (and perhaps why...although valgrind will help more with this type of error).
Run 1: badprog.c
This is an example run of gdb on badprog.c.It demonstrates commonly used gdb commands in a debugging session.Run 2: segfaulter.c
Gdb Compiler
This is an example run of gdb on the segfaulter.c program that segfaults when run.To
Also, you can give just the unique prefix of a command as the command andgdb will execute it. For example, rather than entering the command print x, you can just enter p x to print out the valueof x.
The up and down arrow keys can be used to scroll through previous command lines, so you do not need to re-type them each time.
If you just hit RETURN at the gdb prompt, gdb will execute themost recent previous command again. This is particularly useful if you aresteping through the execution, then you don't have to type nexteach time you want to execute the next instruction, you can just typeit one time and then hit RETURN.
conditional breakpoints
A conditional breakpoint is one that only transfers control to gdb when a certain condition is true. This can be very useful when you only wantgdb control after iteration 1000 of a loop, for example.To set a condition on a breakpoint, use the condition command with thenumber of the breakpoint followed by the condition on which to triggerthe breakpoint. Here is an example where I'm setting a conditionalbreakpoint in the loops.c programthat will only be triggered when the condition (i >= 150) is true:
breakpoints in C++ programs
One complication with gdb and C++ programs, is that you need to specify methods and data members using the 'classname::' prefix. In addition, you often need to use a leading ' before a name for gdb to find the symbol, and if methods are overloaded, you need to specify which method it is by listing its full prototype (actually, if you hit TAB gdb will list all possible matches for you and you can pick one of those).For example, to set a break point in funciton pinPage of the BufMgr class,I'd do the following:This looks pretty icky, but really I just type break 'BufMgr::p then hit TAB for automatic completion.will list all methods of the BufMgr class, then you can just pick from the list the method you want to put the breakpoint in.
debugging multi-threaed processes in gdb
Here are some basics about using gdb to debug pthread programs, and somegeneral advice for debugging multi-threaded processes, and some links to othergdb and pthreads resources: debugging pthreads programsattaching gdb to a running process
- get the process's pid
- attach gdb to the running process At this point the process is stopped by gdb; you have the gdb prompt that you can use issue gdb commands like setting breakpoints, or printing out program state before continuing execution.
Debugging
attach_example.c) you can continue its execution from the gdb prompt in one of two ways:following a process on a fork
You can set gdb to follow either the parent or the child process on a fork (the default is to follow the parent): By setting breakpoints in the child path of code, and then doing: gdb will follow the child process after the fork. See debugging forks for more information.signal control
In gdb you can send the process a signal: Sometimes your process receives signals and you would like to have gdb perform some action when certain signals are delived to the debugged process. For example, if your program issues a bad adress, it will receive a SIGBUS signal and usually exit. The default behavior of gdb on a SIGBUS it to let the process exit. If, however, you want to examine program state when it recieves a SIGBUS, you can specify that gdb handle this singal differently: You can list how gdb is handling signals using info:Running ddd creates a .ddd directory in your home directory andwill save settings to files here, so that you don't need to resetall your preferences from scratch. You can click and drag to change thesizes of subwindows and choose Menu options to display (or not) certainmenus, register values, machine code, etc.
- To view assembly code: under Source menu choose 'Display Machine Code' or Alt+4
- If ddd hangs with 'Waiting until gdb ready' message, then one way to fix this is to wipe out your .ddd directory (you will lose all your saved settings):
Gdb Online Compiler
common gdb commands (from above)Further Information
example gdb sessions (from above)
GDB quick reference card
A very complete GDB reference
Using GDB within Emacs by Ali Erkan