How to Use GDB Backtrace to Debug Strack Frame using C Example Code

by Lakshmanan Ganapathy on January 9, 2014

GDB is an essential tool for programmers to debug their code.

Breakpoints are the way to tell GDB to stop or pause the program execution at certain line, or function, or address. Once the program is stopped you can examine and change the variable values, continue the program execution from that breakpoint, etc.

Similar to breakpoints, backtrace is also helpful during debugging process to view and navigate the stack frame as explained in this tutorial

This tutorial requires some basic understanding of stack frame that we discussed in our memory layout of a process article.

C Code Example for GDB Backrace

The following C program code example will be used in this tutorial to explain GDB backtrace.

	 	 
#include<stdio.h>	 	 
void func1();	 	 
void func2();	 	 
int main() {	 	 
 int i=10;	 	 
 func1();	 	 
 printf("In Main(): %d\n",i);	 	 
}	 	 
void func1() {	 	 
 int n=20;	 	 
 printf("In func1(): %d\n",n);	 	 
 func2();	 	 
}	 	 
void func2() {	 	 
 int n = 30;	 	 
 printf("In func2() : %d\n",n);	 	 
}	 	 
# cc -g stack.c	 	 

In a above code, main() will call func1() which inturn calls func2(). We will show how to examine the stack at each stage.

Getting a Backtrace in GDB

In this example, we had set a breakpoint at line number 20. So, the code stopped at func2() line 20 when we use gdb.

You can get the backtrace using ‘bt’ command as shown below.

	 	 
# gdb	 	 
(gdb) file ./a.out 	 	 
Reading symbols from /home/lakshmanan/a.out...done.	 	 
(gdb) b 20	 	 
Breakpoint 1 at 0x400579: file stack.c, line 20.	 	 
(gdb) run	 	 
Starting program: /home/lakshmanan/./a.out 	 	 
In func1(): 20	 	 
Breakpoint 1, func2 () at stack.c:20	 	 
20 printf("In func2() : %d\n",n);	 	 

We already discussed how we can use GDB breakpoints to pause and continue a program execution from a particular point for debugging purpose.

From the output below, we know that currently we are in func2(), which is called by func1(), which was inturn called by main().

	 	 
(gdb) bt	 	 
#0 func2 () at stack.c:20	 	 
#1 0x0000000000400568 in func1 () at stack.c:15	 	 
#2 0x0000000000400525 in main () at stack.c:9	 	 

Moving from one Frame to Another

You can move between the stack frames using ‘frame [number]‘ as shown below.

In the below snippet, still the func2() is not returned, but we are able to move to frame 1 (which is func1) and examine the variable n’s value which is present inside func1().

	 	 
(gdb) bt	 	 
#0 func2 () at stack.c:20	 	 
#1 0x0000000000400568 in func1 () at stack.c:15	 	 
#2 0x0000000000400525 in main () at stack.c:9	 	 
(gdb) p n	 	 
$1 = 30	 	 
(gdb) frame 1	 	 
#1 0x0000000000400568 in func1 () at stack.c:15	 	 
15 func2();	 	 
(gdb) p n	 	 
$2 = 20	 	 

In the snippet below, we have executed the next 2 instructions using ‘n 2′, and func2 is returned.

Now ‘bt’ tells you that you are currently in func1() which is called from main(), and the stack frame for func2 is gone.

	 	 
(gdb) n 2	 	 
In func2() : 30	 	 
func1 () at stack.c:16	 	 
16 }	 	 
(gdb) bt	 	 
#0 func1 () at stack.c:16	 	 
#1 0x0000000000400525 in main () at stack.c:9	 	 

Get Information about a Stack Frame

You can get the information about a particular frame using ‘info frame [number]‘ as shown below.

	 	 
(gdb) info frame 0	 	 
Stack frame at 0x7fffffffe150:	 	 
 rip = 0x400568 in func1 (stack.c:16); saved rip 0x400525	 	 
 called by frame at 0x7fffffffe170	 	 
 source language c.	 	 
 Arglist at 0x7fffffffe140, args: 	 	 
 Locals at 0x7fffffffe140, Previous frame's sp is 0x7fffffffe150	 	 
 Saved registers:	 	 
 rbp at 0x7fffffffe140, rip at 0x7fffffffe148	 	 

Linux Sysadmin Course Linux provides several powerful administrative tools and utilities which will help you to manage your systems effectively. If you don’t know what these tools are and how to use them, you could be spending lot of time trying to perform even the basic administrative tasks. The focus of this course is to help you understand system administration tools, which will help you to become an effective Linux system administrator.
Get the Linux Sysadmin Course Now!

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

{ 3 comments… read them below or add one }

1 aL January 10, 2014 at 7:39 am

p n shows this value instead of the value of n…. $2 = 32767 do you know why? :)

func2 is in line 14… not 20… whole program is 18 lines long

2 Leslie Satenstein January 10, 2014 at 3:35 pm

Why did you not show the compiler options to compile for debug? It would have helped to be able to duplicate your example.

Perhaps I could find an example from youtube. If I do, I will reference it here.,

3 Andy January 18, 2014 at 11:57 am

since you covering setting breakpoint at line 20, b 20, it’s better if you add row number to your “C program code example”…thx a lot for your efforts on TGS…

Leave a Comment

Previous post:

Next post: