pages tagged gdbyakkinghttp://yakking.branchable.com/tags/gdb/yakkingikiwiki2013-12-04T12:00:29ZIntroduction to GDBhttp://yakking.branchable.com/posts/gdb/Richard Ipsum2013-12-04T12:00:29Z2013-12-04T12:00:07Z
<p>This article introduces the GNU Debugger (GDB).</p>
<p>Here we have code to build a list.</p>
<pre><code>#include <stdio.h>
#include <stdlib.h>
struct node {
int element;
struct node *next;
};
struct node *append(struct node *l, int x)
{
struct node *n = malloc(sizeof (n));
n->element = x;
n->next = NULL;
if (l == NULL)
l = n;
else {
while (l != NULL)
l = l->next;
l->next = n;
}
return l;
}
int main(void)
{
struct node *l = append(NULL, 0);
append(l, 1);
append(l, 2);
return EXIT_SUCCESS;
}
% gcc -o list list.c
% ./list
Segmentation fault
</code></pre>
<p>GDB can help you find the cause of a segfault, add <code>-g</code> to your compile
command and re-run. <code>-g</code> tells gcc to emit debugging information. The
debugging information is used by gdb.</p>
<pre><code>% gcc -o list list.c -g
% gdb ./list
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/richardipsum/Desktop/list...done.
(gdb) run
Starting program: /home/richardipsum/Desktop/list
Program received signal SIGSEGV, Segmentation fault.
0x000000000040056a in append (l=0x0, x=1) at list.c:21
21 l->next = n;
</code></pre>
<p>GDB shows us where the segfault occurs.</p>
<h1>Breakpoints</h1>
<p>GDB lets the user set a break point, this is a point
in the code where execution can be stopped, which allows the user to
examine the state of the program's objects. Afterward the user can resume
execution.</p>
<p>Here we set a breakpoint at line 13, just after we assign our element
to its node.</p>
<pre><code>% gcc -o list list.c -g
% gdb ./list
% ...
% ...
% (gdb) break 13
Breakpoint 1 at 0x400532: file list.c, line 13.
(gdb) run
Starting program: /home/richardipsum/Desktop/list
Breakpoint 1, append (l=0x0, x=0) at list.c:13
13 n->next = NULL;
</code></pre>
<p>At this point <code>n->element</code> should have been assigned the value of <code>x</code> (0),
to confirm this we can use gdb's print command.</p>
<pre><code>% (gdb) print n->element
% $1 = 0
</code></pre>
<p>To resume execution we use the continue command.</p>
<pre><code>(gdb) continue
Continuing.
Breakpoint 1, append (l=0x601010, x=1) at list.c:13
13 n->next = NULL;
</code></pre>
<p>Notice that <code>l</code> now has a value of <code>0x601010</code>, our first call to append
appended the node with element 0 to the empty list and
returned a pointer to a node located at address <code>0x601010</code>,
the beginning of the list <code>l</code>. Our second call to append will append the node
with element 1 to <code>l</code>.</p>
<h1>Stepping</h1>
<p>Another useful command is the <code>step</code> command, this allows the user to
examine execution step by step.</p>
<p>Note that if you hit return without entering a command gdb will assume
the command entered previously, this makes stepping very convenient.</p>
<pre><code>(gdb) step
15 if (l == NULL)
(gdb)
18 while (l != NULL)
(gdb)
19 l = l->next;
(gdb)
18 while (l != NULL)
(gdb)
21 l->next = n;
(gdb)
Program received signal SIGSEGV, Segmentation fault.
0x000000000040056a in append (l=0x0, x=1) at list.c:21
21 l->next = n;
(gdb) print l
$1 = (struct node *) 0x0
</code></pre>
<p><code>l</code> is NULL, dereferencing NULL is undefined and causes a segfault on the
computer running this code.</p>
<p>GDB is a powerful tool, it can do a lot more than has been shown here,
for more information see <a href="https://sourceware.org/gdb/onlinedocs/gdb">gdb online docs</a>.</p>