0% found this document useful (0 votes)
5 views

Lab4 Gdb Assembly

The document is a tutorial on using the GNU Debugger (GDB) for debugging various programming languages. It covers basic GDB usage, debugging pointers, arrays, loops, function calls, and advanced features like watchpoints. Additionally, it explains stack frames, function call mechanics, and provides examples to illustrate these concepts.

Uploaded by

112114006
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

Lab4 Gdb Assembly

The document is a tutorial on using the GNU Debugger (GDB) for debugging various programming languages. It covers basic GDB usage, debugging pointers, arrays, loops, function calls, and advanced features like watchpoints. Additionally, it explains stack frames, function call mechanics, and provides examples to illustrate these concepts.

Uploaded by

112114006
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

GNU debugger

DS2040, Satyajit Das

February 6, 2025

1 GDB Debugging Tutorial


1.1 Overview
The GNU Debugger (GDB) is a portable debugger that runs on many Unix-like systems and works
for many programming languages, including Ada, Assembly, C, C++, D, Fortran, Haskell, Go,
Objective-C, OpenCL C, Modula-2, Pascal, Rust, and partially others. (Wikipedia).
For quick reference, please refer to https://users.ece.utexas.edu/ adnan/gdb-refcard.pdf

1.2 Part A: Basic GDB Usage


Hello GDB Example
// hello . c
# include < stdio .h >

int main () {
printf ( " Hello , GDB !\ n " ) ;
return 0;
}

Compile and Run in GDB:


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

Commands

• run, break main, info breakpoints, delete <n>, continue

1.3 Part B: Debugging Pointers


pointer_bug.c
# include < stdio .h >
# include < stdlib .h >

int main () {
int * p = NULL ;
int x = 10;

p = &x; // correct pointer assignment

// Uncomment to see bug scenarios :

1
// p = NULL ;
// p = ( int *) 0 x1234 ;

printf ( " Value of * p is : % d \ n " , * p ) ;


return 0;
}

• gdb ./pointer_bug

• Break at main, step, print p, print *p

• Uncomment lines to cause segfault, use backtrace to see crash.

1.4 Part C: Debugging Arrays and Loops


array_loop.c
# include < stdio .h >

int main () {
int arr [5] = {1 , 2 , 3 , 4 , 5};
int sum = 0;
int i ;

for ( i = 0; i < 5; i ++) {


sum += arr [ i ];
}

printf ( " Sum is : % d \ n " , sum ) ;


return 0;
}

• Compile with -g, run in GDB

• break array_loop.c:10, step, inspect i, sum.

• Change loop to i <= 5 to force out-of-bounds.

1.5 Part D: Debugging Function Calls


multi_func.c
# include < stdio .h >

int multiply ( int a , int b ) {


return a * b ;
}

int sum_of_products ( int x , int y ) {


// Suppose there ’s a logic bug
return multiply (x , y ) + multiply (x , 2) ;
}

int main () {
int m = multiply (3 , 4) ;
printf ( " 3 * 4 = % d \ n " , m ) ;

2
int s = sum_of_products (2 , 5) ;
printf ( " sum_of_products (2 , 5) = % d \ n " , s ) ;

return 0;
}

• Break in main, step into multiply, check info args.

• backtrace to see call chain, finish to exit current function.

1.6 Bonus: Watchpoints & Advanced Features


• watch sum to break when sum changes.

• Conditional breakpoints: break array_loop.c:10 if i == 3.

• Examine memory: x/8w &arr.

1.7 Wrap-Up
• step, next, finish, backtrace, info locals, info args.

• Practice with real bugs, valgrind if memory issues suspected.

2 Debugging Stack Frames, Function Calls, Arguments, Returns


2.1 Overview
• Focus on stack frames, function call mechanics, arguments, return values.

• Demonstrates how to examine them in GDB.

2.2 Example 1: Basic Function Call / Return


basic_call.c
# include < stdio .h >

// multiply two numbers


int multiply ( int a , int b ) {
int result = a * b ;
return result ;
}

// calls multiply multiple times


int do_calculations ( int x ) {
int val1 = multiply (x , x + 1) ;
int val2 = multiply ( x + 2 , x + 3) ;
int sum = val1 + val2 ;
return sum ;
}

int main () {
int input = 3;

3
int output = do_calculations ( input ) ;
printf ( " Final result = % d \ n " , output ) ;
return 0;
}

• Break in main, step into do_calculations.

• info args, info locals, watch how %rax is used for returns.

• backtrace to see call hierarchy.

2.3 Example 2: Recursion and the Stack (factorial)


factorial.c
# include < stdio .h >

long factorial ( int n ) {


if ( n <= 1) {
return 1;
} else {
return n * factorial ( n - 1) ;
}
}

int main () {
int val = 5;
long fact = factorial ( val ) ;
printf ( " factorial (% d ) = % ld \ n " , val , fact ) ;
return 0;
}

• Multiple stack frames from recursion.

• break factorial, run, then backtrace.

• frame <n> or up/down to move among frames.

2.4 Example 3: Stack Corruption Demo


stack_corruption.c
# include < stdio .h >
# include < string .h >

void copy_data ( char * dest , const char * src , int size ) {


// ignoring bounds for demonstration
strcpy ( dest , src ) ; // potential overflow
}

int main () {
char buffer [8] = " OK " ;
int secret_value = 123;

printf ( " secret_value = % d \ n " , secret_value ) ;

4
// Overwrite the buffer with a bigger string
copy_data ( buffer , " AAAAAAAAAAAAAAAAAAAA " , 20) ;

// Did secret_value change ?


printf ( " secret_value ( after ) = % d \ n " , secret_value ) ;
return 0;
}

• Run in GDB, step into copy_data, watch memory near buffer.

• x/32bx &buffer, compare with &secret_value.

2.5 Wrap-Up
• Understand how stack frames store local vars, arguments, return address.

• GDB commands: info frame, info registers, disassemble /m.

• Navigating frames: bt, frame <n>, up, down.

You might also like