CS29206 Systems Programming Laboratory Spring 2024 Introduction To GDB
CS29206 Systems Programming Laboratory Spring 2024 Introduction To GDB
Spring 2024
Introduction to gdb
Abhijit Das
Pralay Mitra
Why debuggers?
• Writing error-free codes (particularly large ones) is every programmer’s dream.
• Compilation errors
• Logical errors
• Runtime errors
int main ()
{
int x1, y1, x2, y2, x3, y3;
double area;
exit(0);
}
Running codes with gdb
(gdb) list
21 if (area < 0) area = -area;
22 area /= 2;
23
24 printf("Area of the triangle is %lf\n", area);
25
26 exit(0);
27 }
(gdb) list
Line number 28 out of range; tarea.c has 27 lines.
(gdb) list 15
10
11 printf("Enter the coordinates of the first corner: ");
12 scanf("%d%d", &x1, &y1);
13 printf("Enter the coordinates of the second corner: ");
14 scanf("%d%d", &x2, &y2);
15 printf("Enter the coordinates of the third corner: ");
16 scanf("%d%d", &x3, &y3);
17
18 area = x1 * (y2 - y3);
19 area += x2 * (y1 - y3);
(gdb) list 18,22
18 area = x1 * (y2 - y3);
19 area += x2 * (y1 - y3);
20 area += x3 * (y1 - y2);
21 if (area < 0) area = -area;
22 area /= 2;
(gdb)
Set a breakpoint and step through your code
(gdb) break 11
Breakpoint 1 at 0x11d0: file tarea.c, line 11.
(gdb) run
Starting program: /home/abhij/IITKGP/course/lab/SPL/Spring22/prog/gdb/a.out
Program to calculate the area of a triangle with integer coordinates
Value history: The printed values are stored as $1, $2, . . . , and can be accessed later.
Watching variables after every step
(gdb) break 16
Breakpoint 1 at 0x123b: file tarea.c, line 16.
(gdb) run
...
Breakpoint 1, main () at tarea.c:16
16 scanf("%d%d", &x3, &y3);
(gdb) n
Enter the coordinates of the third corner: -1 5
18 area = x1 * (y2 - y3);
(gdb) display area
1: area = 6.953355807476115e-310
(gdb) n
19 area += x2 * (y1 - y3);
1: area = -36
(gdb) n
20 area += x3 * (y1 - y2);
1: area = -18
(gdb) n
21 if (area < 0) area = -area;
1: area = -33
(gdb) n
22 area /= 2;
1: area = 33
(gdb) n
24 printf("Area of the triangle is %lf\n", area);
1: area = 16.5
(gdb) continue
Continuing.
Area of the triangle is 16.500000
[Inferior 1 (process 8608) exited normally]
(gdb)
Setting variables: The program
setvar.c
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int a, b;
a = 5;
b = 8;
printf("max(%d,%d) = %d\n", a, b, (a >= b) ? a : b);
printf("max(%d,%d) = %d\n", a, b, (a >= b) ? a : b);
exit(0);
}
Setting variables: Run gdb
average.c
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int n, x, sum;
n = sum = 0;
printf("Keep on entering non-negative integers. Enter a negative integer to end.\n");
while (1) {
printf("Next number: "); scanf("%d", &x);
if (x < 0) break;
++n; sum += x;
}
printf("Average of the numbers entered is %lf\n", (double)sum / (double)n);
exit(0);
}
Conditions and loops: Example run
double tarea ( int x1, int y1, int x2, int y2, int x3, int y3 )
{
double area;
int main ()
{
int x1, y1, x2, y2, x3, y3;
double area;
fib.c
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int n, f;
n = 8;
f = Fib(n);
printf("F(%d) = %d\n", n, f);
exit(0);
}
Program with a recursive function: Line numbers
(gdb) l
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int Fib ( int n )
5 {
6 if (n < 0) return -1;
7 if (n <= 1) return n;
8 return Fib(n-1) + Fib(n-2);
9 }
10
(gdb) l
11 int main ()
12 {
13 int n, f;
14
15 n = 8;
16 f = Fib(n);
17 printf("F(%d) = %d\n", n, f);
18 exit(0);
19 }
(gdb)
Function call with next
Stepping in average.c
(gdb) break main
Breakpoint 1 at 0x11a9: file average.c, line 5.
(gdb) run
Starting program: /home/abhij/IITKGP/course/lab/SPL/Spring22/prog/gdb/a.out
• Note: up/down does not change the execution to go up or down. You only move inside the
stack, and can see the details of the frames in the stack.
Program to demonstrate the call stack
callstack.c
#include <stdio.h>
#include <stdlib.h>
void h ( int n )
{
printf("+++ Called h(%d)\n", n);
}
void g (int n )
{
if (n >= 3) h(n-3);
}
void f ( int n )
{
while (n >= 0) { g(n); n -= 2; }
}
int main ()
{
int i;
for (i=0; i<5; ++i) f(i);
exit(0);
}
The call tree
main()
printf() printf()
View the call stack
(gdb) break h
Breakpoint 1 at 0x1169: file callstack.c, line 5.
(gdb) run
Starting program: /home/abhij/IITKGP/course/lab/SPL/Spring22/prog/gdb/a.out
(gdb) bt
#0 Fib (n=1) at fib.c:5
#1 0x00005555555551ad in Fib (n=2) at fib.c:8
#2 0x000055555555519e in Fib (n=3) at fib.c:8
#3 0x000055555555519e in Fib (n=4) at fib.c:8
#4 0x000055555555519e in Fib (n=5) at fib.c:8
#5 0x000055555555519e in Fib (n=6) at fib.c:8
#6 0x000055555555519e in Fib (n=7) at fib.c:8
#7 0x000055555555519e in Fib (n=8) at fib.c:8
#8 0x00005555555551d3 in main () at fib.c:16
(gdb) c
Continuing.
Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Type "apropos -v word" for full documentation of commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb) help step
Step program until it reaches a different source line.
Usage: step [N]
Argument N means step N times (or till program stops for another reason).
(gdb) help set var
Evaluate expression EXP and assign result to variable VAR.
Usage: set variable VAR = EXP
...
Practice exercises
1. Explain how you can do the following tasks using the list directive of gdb.
(a) Start the listing of a specified function.
(b) Change the number of lines printed in each list directive.
(c) List a file backward. (You have a 1000-line file. Normal listing prints lines 1–10, 11–20, 21–30, . . . , 991–1000.
You want to list lines 991–1000, 981–990, . . . , 11–20, 1–10 in that order. You should avoid specifying the line
numbers explicitly.)
2. You have written a program in four .c files. The three files part1.c, part2.c and part3.c implement some
functions. The file allparts.c contains the main function (along possibly with some others). You include the
individual parts as #include "partx.c" in allparts.c. Show how you should compile to generate the final
executable file a.out with debugging enabled. You run this using gdb. If you use the list directive, what do you
see? Explain how you can list the individual part files partx.c (with line numbers). Also explain how you can set
breakpoints at specified line numbers in the part files.
3. You have the same situation as in the previous exercise. But now, you do not #include "partx.c" in allparts.c.
You instead generate individual object files part1.o, part2.o, and part3.o. Finally, you combine these object files
and allparts.c to generate an a.out with debugging enabled. Mention the compilation commands you use in the
process. You run a.out using gdb. If you use the list directive, what do you see? Explain how you can list the
individual part files partx.c (with line numbers). Also explain how you can set breakpoints at specified line numbers
in the part files.
Practice exercises
4. Repeat the last two exercises under the assumption that the part files partx.c reside in a subdirectory.
5. How can you load or replace an executable file for running, from the command prompt of gdb?
6. How can you re-run a program in gdb from the beginning? What happens to the breakpoints set in the earlier run?
The values of the variables set in the earlier run? The value history?
7. How can you print the value history in gdb? How can you print variables or expressions without sending the printed
value to the value history?
8. Study how to ignore breakpoints.
9. Explain how you can use new gdb variables not defined in the source file(s).
10. [Conditional break] You have the following loop (with the specified line numbers) in your C program.
You notice that the program encounters a segmentation fault, because p unexpectedly becomes NULL at line 234 for
some (not all) value(s) of n. Propose a break instruction for gdb so that you can easily detect whenever this happens
for the first time. Also explain how you can get the value of n at this point.
Practice exercises
11. How can you stop the display of variables?
12. You have the following loop (with the specified line numbers) in your C program.
Suppose that the loop works without errors for 0 6 n < n0 , and some problem happens in the return values of the
function calls f(n) for n0 6 n < 1000000. You want to locate the exact value of n0 using gdb. Assume that you
can understand a faulty return value by simply inspecting it. Propose an efficient strategy of doing this interactively
from the gdb prompt.
13. [Watchpoints] A breakpoint is a point where the execution of a program in gdb stops conditionally or uncondition-
ally. A watchpoint is a point where the execution stops whenever the value of a variable or expression changes. This
can often be a powerful debugging tool. For example, if a buffer overflow corrupts some variable(s) unintentionally,
the source of the problem can be effectively identified by this feature. Investigate how you can set a watchpoint, list
all watchpoints set, enable/disable/delete watchpoints.
14. Investigate how you can examine the contents of your program’s memory using the x command.
Practice exercises
15. You set a breakpoint at the first printf line in the following program.
int main ()
{
int i, A[5] = {15,16,17};
printf("Hello\n");
for (i=0; i<5; ++i)
printf("A[%d] = %d\n", i, A[i]);
}
Examine what x/5wx A, x/5wx A+1, x/5wx A-1, and x/1wx &i print at the breakpoint. Explain. Notice that i is
uninitialized at this point.
16. You write a C program in which Line 100 (this line is in your main() function) makes the following assignment.
z = f(x) + g(y);
Here, f() and g() are two functions in your program, and are called for the first time in this line. Both these functions
are called multiple times later, but you suspect that there is some problem in the first call g(y). You need to scrutinize
how g() works line by line only in the first call (but not in the later calls). Also, you do not want to scrutinize the line-
by-line working of f() in any of its calls. Explain how you can use gdb interactively to solve this debugging problem.
Notice that you do not know beforehand whether f(x) or g(y) is computed first before the addition and assignment
to z.
Practice exercises
17. Repeat the last exercise if the line z = f(x) + g(y); makes the last call of g().
18. You write a C program in which Line 64 (this line is in your main() function) makes the following assignment.
t = g(f(n));
Here, f() and g() are two functions in your program, and both are called multiple times before and after this line.
You suspect that there is some problem in the call of g() in this line, so you need to scrutinize the line-by-line working
of g() only for this call. You do not want to scrutinize the line-by-line working of any other call of g() or any call
of f(). Explain how you can use gdb interactively to solve this debugging problem. Assume that f(n) returns the
correct value.
19. A function myfunc() in your C program has a loop from Line 123 to Line 127, which is supposed to set a local
int variable t to a value greater than or equal to 10 when the loop ends. In Line 128 (also inside myfunc()), you
make a division by t. Therefore if the loop breaks (due to some bug) with t = 0, then the program encounters a
division-by-zero error, and terminates abnormally. You do not want this to happen. Assume that myfunc() is called
only once and from the main() function. If t is non-zero in Line 128, you allow the program to continue normally. If t
is zero, you go back to main() without proceeding further in the function. Explain how you can use gdb interactively
to achieve this.
20. Suppose that you want to count how many times a function f() is called in your C program. Explain how you can
automate this process using gdb.