gdb command

 

Absolutely — the gdb (GNU Debugger) is one of the most powerful tools for teaching program debugging, process control, and memory management, which directly connects to core Operating Systems concepts.



 gdb (GNU Debugger)

Purpose

gdb is the GNU Project Debugger, used to debug programs written in languages like C, C++, and Fortran.
It allows you to:

  • Run programs step by step

  • Examine variables and memory

  • Set breakpoints to stop execution at specific points

  • Inspect call stacks and understand crashes


Basic Syntax

gdb [options] [program] [core]

Typical usage:

gdb ./a.out

Here, a.out is your compiled executable (from a C or C++ program).


⚙️ Before Using gdb

You must compile your C program with debugging information included:

gcc -g myprogram.c -o myprogram

The -g option tells the compiler to include debugging symbols (function names, variable names, etc.) in the binary.


📘 Starting GDB

Start gdb with your program:

gdb ./myprogram

You’ll see:

GNU gdb (GDB) 13.1 Reading symbols from ./myprogram... (gdb)

Now you’re inside the gdb interactive prompt.


🧩 Commonly Used GDB Commands

CommandDescription
run        Start the program under gdb
break <line_number>        Set a breakpoint at a specific line
break <function_name>        Set a breakpoint at a function
next            Execute the next line (skips over function calls)
step        Execute the next line (enters into functions)
continue        Continue execution until the next breakpoint
print <variable>        Display the value of a variable
backtrace        Show the function call stack
list        Show source code around the current line
info locals        Show all local variables
quit        Exit gdb

Breakpoint Related Commands
info breakpoints         List all breakpoints
delete <num>                Delete a specific breakpoint
delete                           Delete all breakpoints
disable <num>              Temporarily disable a breakpoint
enable <num>                Re-enable a disabled breakpoint

🧪 Example: Debugging a Simple Program

C Program: buggy.c

#include <stdio.h> int main() { int a = 5, b = 0; int c = a / b; // Division by zero printf("Result = %d\n", c); return 0; }

Step 1: Compile with -g

gcc -g buggy.c -o buggy

Step 2: Run with gdb

gdb ./buggy

Step 3: Start the Program

At the (gdb) prompt, type:

run

You’ll see:

Program received signal SIGFPE, Arithmetic exception. 0x0000000000401134 in main () at buggy.c:5 5 int c = a / b; // Division by zero

This shows exactly where the program crashed and why.


Step 4: Inspect Variables

(gdb) print a $1 = 5 (gdb) print b $2 = 0

You can see that the division by zero occurred because b = 0.


Step 5: List Source Around Current Line

(gdb) list

Step 6: Quit

(gdb) quit

🧩 Setting and Using Breakpoints

Example Program: example.c

#include <stdio.h> void greet() { printf("Hello, world!\n"); } int main() { int x = 10; greet(); printf("x = %d\n", x); return 0; }

Steps:

gcc -g example.c -o example gdb ./example

Inside gdb:

(gdb) break main Breakpoint 1 at 0x1149: file example.c, line 7. (gdb) run (gdb) next (gdb) step (gdb) print x (gdb) continue

You can watch the program execute line by line, see when functions are called, and inspect values as they change.


🧩 Debugging a Running Process

Attach gdb to a process that’s already running:

gdb -p <pid>

This is useful for diagnosing stuck or crashed processes.


Sample Lab Exercise

Task:

  1. Write a small program that computes a factorial but forgets to initialize a variable.

  2. Compile it with gcc -g.

  3. Use gdb to:

    • Run the program

    • Set a breakpoint at the loop

    • Step through the code

    • Print variable values at each iteration

🧩 Step 1: Write the C Program (with a Bug)

File name: fact.c

#include <stdio.h> int main() { int n, i, fact; printf("Enter a number: "); scanf("%d", &n); for(i = 1; i <= n; i++) { fact = fact * i; // ❌ fact is used before being initialized } printf("Factorial of %d = %d\n", n, fact); return 0; }

🔍 Problem

The variable fact is not initialized, so it contains garbage data.
This causes the output to be incorrect — a perfect case to use gdb for investigation.


🧩 Step 2: Compile with Debug Information

gcc -g fact.c -o fact

The -g option adds debugging symbols needed for gdb.


🧩 Step 3: Start the Debugger

gdb ./fact

You’ll see the GDB prompt:

(gdb)

🧩 Step 4: Set a Breakpoint at the Loop

List the code first:

(gdb) list

You’ll see something like:

1 #include <stdio.h> 2 3 int main() { 4 int n, i, fact; 5 printf("Enter a number: "); 6 scanf("%d", &n); 7 8 for(i = 1; i <= n; i++) { 9 fact = fact * i; 10 } 11 12 printf("Factorial of %d = %d\n", n, fact); 13 return 0; 14 }

Now set a breakpoint at the loop (say, line 8):

(gdb) break 8 Breakpoint 1 at 0x1149: file fact.c, line 8.

🧩 Step 5: Run the Program

(gdb) run

Enter a number when prompted, for example:

Enter a number: 4

The program stops at the breakpoint:

Breakpoint 1, main () at fact.c:8 8 for(i = 1; i <= n; i++) {

🧩 Step 6: Step Through the Code

Execute one line at a time:

(gdb) next

or if you want to step inside function calls (not needed here):

(gdb) step

Now inside the loop, you can repeatedly press next to move line by line.


🧩 Step 7: Print Variable Values

Before the loop starts:

(gdb) print fact $1 = 32767 <-- (random garbage value, uninitialized) (gdb) print i $2 = 1 (gdb) print n $3 = 4

After the first iteration, press next again and recheck:

(gdb) print fact

You’ll see the value changing incorrectly — this helps students understand the effect of using uninitialized variables.


🧩 Step 8: Fix the Bug

Now exit gdb:

(gdb) quit

Modify the program to initialize fact = 1;

✅ Corrected Version:

#include <stdio.h> int main() { int n, i, fact = 1; printf("Enter a number: "); scanf("%d", &n); for(i = 1; i <= n; i++) { fact = fact * i; } printf("Factorial of %d = %d\n", n, fact); return 0; }

Compile and run again:

gcc -g fact.c -o fact ./fact

Output:

Enter a number: 4 Factorial of 4 = 24

Learning Outcome

Students will:

  • Understand the role of debugging symbols (-g flag).

  • Learn how to set breakpoints, run, step through, and print variable values in gdb.

  • See the practical effect of an uninitialized variable


Comments

Popular posts from this blog

Operating Systems OS Lab PCCSL407 Semester 4 KTU BTech CS 2024 Scheme - Dr Binu V P

Exploring the /proc file system

ps command