Getting to Know gdb
gdb provides two forms of single-step execution. The next command executes an entire function when it encounters a call, while the step command enters the function and keeps going one statement at a time. To understand the difference between these two commands, look at their behavior in the context of debugging a simple program. Consider the following example:
$ gdb qsort2 (gdb) break main Breakpoint 6 at 0x235c: file qsort2.c, line 40. (gdb) run Breakpoint 6, main () at qsort2.c:40 40 int power=1; (gdb) step 43 printf("Tests with RANDOM inputs and FIXED pivot\n"); (gdb) step Tests with RANDOM inputs and FIXED pivot 45 for (testsize = 10; testsize <= MAXSIZE; testsize *= 10){ (gdb) step 46 gen_and_sort(testsize,RANDOM,FIXED); (gdb) step gen_and_sort (numels=10, genstyle=0, strat=1) at qsort2.c:79 79 s = &start_time; (gdb)
We set a breakpoint at the entry to the main() function, and started single-stepping. After a few steps, we reach the call to gen_and_sort(). At this point, the step command takes us into the function gen_and_sort(); all of a sudden, we're executing at line 79, rather than 46. Rather than executing gen_and_sort() in its entirety, it stepped “into” the function. In contrast, next would execute line 46 entirely, including the call to gen_and_sort().
A number of informational commands vary according to where you are in the program; their arguments and output depend on the current frame. Usually, the current frame is the function where you are stopped. Occasionally, however, you want to change this default so you can do something like display a number of variables from another function.
The commands up and down move you up and down one level in the current call stack. The commands up n and down n move you up or down n levels in the stack. Down the stack means farther away from the program's main() function; up means closer to main(). By using up and down, you can investigate local variables in any function that's on the stack, including recursive invocations. Naturally, you can't move down until you've moved up first—by default you're in the currently executing function, which is as far down in the stack as you can go.
For example, in qsort2(), main() calls gen_and_sort(), which calls qsort2(), which calls swap(). If you're stopped at a breakpoint in swap(), a where command gives you a report like this:
(gdb) where
#0 swap (i=3, j=7) at qsort2.c:134
#1 0x278c in qsort2 (l=0, u=9, strat=1) at
qsort2.c:121
#2 0x25a8 in gen_and_sort (numels=10, genstyle=0,
strat=1) at qsort2.c:90
#3 0x23a8 in main () at qsort2.c:46
(gdb)
The up command directs gdb's attention at the stack frame for qsort2(), meaning that you can now examine qsort2's local variables; previously, they were out of context. Another up gets you to the stack frame for gen_and_sort(); the command down moves you back towards swap(). If you forget where you are, the command frame summarizes the current stack frame:
(gdb) frame
#1 0x278c in qsort2 (l=0, u=9, strat=1) at
qsort2.c:121
121 swap(i,j);
In this case, it shows that we're looking at the stack frame for qsort2(), and currently executing the call to the function swap(). This should be no surprise, since we already now that we're stopped at a breakpoint in swap.
gdb provides a few special commands for working with machine language. First, the info line command is used to tell you where the object code for a specific line of source code begins and ends. For example:
(gdb) info line 121
Line 121 of "qsort2.c" starts at pc 0x277c and
ends at 0x278c.
You can then use the disassemble command to discover the machine code for this line:
(gdb) disassemble 0x260c 0x261c
Dump of assembler code from 0x260c to 0x261c:
0x260c <qsort2>: save %sp, -120, %sp
0x2610 <qsort2+4>: st %i0, [ %fp + 0x44 ]
0x2614 <qsort2+8>: st %i1, [ %fp + 0x48 ]
0x2618 <qsort2+12>: st %i2, [ %fp + 0x4c ]
End of assembler dump.
The commands stepi and nexti are equivalent to step and next but work on the level of machine language instructions rather than source statements. The stepi command executes the next machine language instruction. The nexti command executes the next instruction, unless that instruction calls a function, in which case nexti executes the entire function.
The memory inspection command x (for “examine”) prints the contents of memory. It can be used in two ways:
(gdb) x/nfu addr (gdb) x addr
The first form provides explicit formatting information; the second form accepts the default (which is, generally, whatever format was used for the previous x or print command—or hexadecimal, if there hasn't been a previous command). addr is the address whose contents you want to display.
Formatting information is given by nfu, which is a sequence of three items:
n is a repeat count that specifies how many data items to print;
f specifies what format to use for the output;
u specifies the size of the data unit (e.g., byte, word, etc.).
For example, let's investigate s in line 79 of our program. print shows that it's pointer to a struct tms:
79 s = &start_time;
(gdb) print s
$1 = (struct tms *) 0xf7fffae8
The easy way to investigate further would be to use the command print *s, which displays the individual fields of the data structure.
(gdb) print *s
$2 = {tms_utime = 9, tms_stime = 14,
tms_cutime = 0, tms_cstime = 0}
For the sake of argument, let's use x to examine the data here. The struct tms (which is defined in the header file time.h) consists of four int fields; so we need to print four decimal words. We can do that with the command x/4dw, starting at location s:
(gdb) x/4dw s
0xf7fffae8 <_end+-138321592>: 9 14 0 0
The four words starting at location s are 9, 14, 0, and 0—which agrees with what print shows.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- Linux Systems Administrator
- New Products
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- Designing Electronics with Linux
- Dynamic DNS—an Object Lesson in Problem Solving
- Using Salt Stack and Vagrant for Drupal Development
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)




2 hours 30 min ago
7 hours 1 min ago
7 hours 2 min ago
9 hours 2 min ago
17 hours 47 min ago
18 hours 21 min ago
19 hours 20 min ago
20 hours 10 min ago
1 day 12 min ago
1 day 3 hours ago