GDB Debugging Useful Commands

Steps to Use GDB debugger tool

  1. First compile your c code by passing ‘-g’ flag or include this flag in your Makefile so that binary will compile with this flag, see the below example

      #gcc -g my_prog.c -o my_prog                     // my_prog is binary which can run with gdb

     2.Then  run the executable/binary with gdb tool. See below,

      # gdb my_prog

3. To see the source code, use the command list [Which is only available, if we compile   our source code with -g flag at step#1]
(gdb)  list

1    #include<stdio.h>
2    void func(int a)
3    {
4    int b[]= {1,2,3,4};
5    int i = 0;
6    for (i=0; i<7;i++)
7    printf(“elements are:%d \n”,b[i]);
8    }
9
10    int main()
(gdb)

4. Now set the break point so that  when we run our program, control will directly jumps to there from main function and wait to execute from there

(gdb) break 2                         // which means we set the break point at line number 2

5. Now run the programm by typing the command ‘run’ or simply ‘r’ so that program start executed. We can also use ‘s’ which means it will step into function by function instead of line by line.

(gdb) run or step

(gdb) next                             // next is to execute next line of code in the source code

(gdb)next

(gdb)next

(gdb)next  //like this so on………..

6. To print any variable use ‘print’ ot simply ‘p’ command

(gdb) print  <variable_name>

or

(gdb) p <variable_name>

6.1 To set any variable use ‘set’ command, let say we have a loop to 1000(i<1000) times to execute then if we want to see the output for i =990 then set the variable directly to 990 by following command

(gdb) set variable i =990

(gdb) next

7. To see the local variables use command ‘info locals’

(gdb)info locals                                               // type info and then press TAB button will give you list of available options we can check

(gdb)info breakpoints

(gdb)info stack

(gdb)info functions

8. We can set the watch point to a variable, so when ever variable value is changes we can get that info like below,

(gdb) watch <variable name>                          // say watch i
Hardware watchpoint 2: i
(gdb) n                                                                  //Here i value is changed from 0 to 1
Hardware watchpoint 2: i
Old value = 0
New value = 1

9. Use ‘backtrace’ or simply ‘bt’ to see the stack function frames like at which function we got violation(like SIGSEV etc)

(gdb) n                   // After this we got a SIGSEGV signal

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a5cc80 in _IO_vfprintf_internal (s=0x7ffff7dd2620 <_IO_2_1_stdout_>, format=<optimized out>,
ap=ap@entry=0x7fffffffe438) at vfprintf.c:1632
1632 vfprintf.c: No such file or directory.
(gdb) backtrace
#0 0x00007ffff7a5cc80 in _IO_vfprintf_internal (s=0x7ffff7dd2620 <_IO_2_1_stdout_>, format=<optimized out>,
ap=ap@entry=0x7fffffffe438) at vfprintf.c:1632
#1 0x00007ffff7a63849 in __printf (format=<optimized out>) at printf.c:33
#2 0x0000000000400689 in main () at sample.c:20

10. Use ‘up’ command if the fault is coming by calling a libary function with wrong data, as library function are error free, fault is from our program only…:)

===================

(gdb) up
#1 0x00007ffff7a63849 in __printf (format=<optimized out>) at printf.c:33
33 printf.c: No such file or directory.
(gdb) up
#2 0x0000000000400689 in main () at sample.c:20
20 printf(“%s \n”,*(p+i));

===============

Above output showing that in my sample.c at line 20, calling to printf library function causing the error.

11. When we identified the bug, we will fix it and re-run with gdb, instead of that we can do as first type the command ‘kill’ in gdb(otherwise you cannot compile it in another terminal,it will say resource busy) and  open another terminal and made the fix in the source code and compile it. Then come back to first terminal and type the command ‘run’ then gdb is smart enough to load your newly compiled binary.

(gdb) kill
Kill the program being debugged? (y or n) y             // Now re-compile the program in another tab
(gdb) run
Starting program: /root/c_pgms/gdb/a.out

12. We have a special case where after sometime our binary got fault lets say SIGSEGV so in these type of siatuations we can tell the gdb to lookout the process and give me the debugging info when that fault occured.

12.1 For this first run your binary and then attach the pid of that process to gdb as below,

#ps -Af | grep ‘binary_name’

get the pid from above command say 1992

12.2 Attach the pid to GDB so that it will take care from now,

# gdb binary_name

(gdb) attach <pid>                    // say attach 1992

(gdb) continue                           // This will make our binary will run in gdb context

 

Hope this will helpful……