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 ddd
Getting 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

The purpose of a debugger is to allow you to see what is going on inside yourC program while it runs. In addition, you can use gdb to see what yourprogram was doing at the moment it crashed.

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. dddis 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/

Getting Started with gdb
C and C++ programs compiled with the GNU compiler and the -goption 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:

An abreviated printable version of these is here

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:

    1. n: the repeat count (a postitive integer value)
    2. f: the display format (s:string, i:instruction, x:hex, d:decimal, t:binary, a:address, ...)
    3. u: the units format (number of bytes) (b:byte, h:2bytes, w: 4bytes, g:8bytes)
    Here are some examplesNOTE: format in examine is sticky, for example if you use the command x/csubsequent executions of x will use /c format. you therefore need toexplicitly change the format to /d /c /s etc. for interpreting memorycontents as differnt type from the previous call to x
  • 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

info commands for examining runtime and debugger state:
gdb has a large set of info X commands for displaying information about different types of runtime state and about debugger state. Here is how to list all the info commands in help, and a description of what a few of the info commands do:
using gdb to debug assembly code and examine memory and register values:
ddd is probably easier to use when steping through assembly code than gdb because you can have separate windows that show the disassembled code, the register values, and the gdb prompt.

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/.
  1. 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.
  2. 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

Keyboard Shortcuts in gdb
gdb supports command line completion; by typing in a prefix you canhit TAB and gdb will try to complete the command line for you.

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.

Setting conditional breakpoints and some issues with setting breakpoints in C++ code

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.

Within gdb you can invoke 'make' to rebuid your executable (assumingthat you have a makefile to build your program). This is a nice feature in the case when you have many breakpoints set and do not want to exit gdb, recompile, re-start gdb with the new a.out, and reset all the breakpoints. However, keep in mind that modifying and recompiling your source code from within gdb may result in your breakpoints not being where you think they should be (adding/removing lines of source code can result in your in your breakpoints no longer being where you want them to be in terms ofthe new version of your source code). You can use the disable or deletecommands to disable or delete old breakpoints.
Some Advanced Features

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 programsGdb

attaching gdb to a running process

  1. get the process's pid
  2. 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.
Depending on if the process was explicitly stopped before attaching gdb or not (e.g. did the process call kill(getpid(), SIGSTOP) to stop itself like in the

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

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 Links

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