I love gdb



I love gdb.
GDB is a tool, by which an engineer able to narrow down the issues with the help of features provided by GDB(The GNU Project Debugger). Most of engineers in triage the critical bugs, they must be used gdb. lot of features, various options helping the engineer in trival time. that's why we loved gdb. Yes, I love gdb.
q). What is "debugging" ?
ans).
*.Debugging is the process of removing bugs from computer programs. On one end of the spectrum, debugging means staring at your source code until you see the bug. An infinitely more effective method is to use a special program called a "debugger".
q). What is a "debugger" ?
ans).
*.A debugger is a program that runs other programs. A debugger lets the user (programmer) stop running the program at any time and poke around internally. You can examine and change memory contents, call functions, and look at system registers. Besides all these fun things, a debugger can be used to fix your programs.
q). Why use a debugger? Isn't printf/cout/System.out.println good enough?
ans).
*.Using a debugger is (generally) the most efficient way to find bugs in your program. Having your program print debugging output is a valid method of finding bugs, and in some cases is the only/easiest way to go. Debuggers show their strength when it comes to common bugs like infinite loops or segmentation faults. You can spin your wheels for hours printing output, where a debugger would point out the problem instantly.
q). What about xdb? Visual Debugger? Where is my GUI?!?
ans).
*.Visual debuggers are great. They make debugging much easier. But you won't always have a visual environment to work in. If you learn to use a command-line debugger like gdb, you can use any debugger in existence, visual or not. Furthermore, for some applications special debuggers have been built, and these debuggers are generally command-line only (eg: kdb, the kernel debugger).
Q). Is gdb only meant for C language?
*.The following sections detail to what degree each source language is supported by gdb.
C: C and C++
q).Is gdb paid version software tool?
*.GDB is free software released under the GNU General Public License (GPL).
Compile it with the -g flag so that gdb has debug information to work with, and then feed it to gdb.
gcc -g myprogram.c
gcc -g server.c -o server

g++ -g main.c
*.A Debugging Symbol Table maps instructions in the compiled binary program(a.out) to their corresponding variable, function, or line in the source code. This mapping could be something like:

Program instruction = item name, item type, original file, line number defined.

*.Symbol tables may be embedded into the program or stored as a separate file. So if you plan to debug your program, then it is required to create a symbol table which will have the required information to debug the program.

*.We can infer the following facts about symbol tables:
1.A symbol table works for a particular version of the program – if the program changes, a new table must be created.

2.Debug builds are often larger and slower than retail (non-debug) builds; debug builds contain the symbol table and other ancillary(సహకార) information.

3.If you wish to debug a binary program(a.out) you did not compile yourself, you must get the symbol tables from the author.

*.To let GDB be able to read all that information line by line from the symbol table, we need to compile it a bit differently. Normally we compile our programs as:

gcc hello.c -o hello
 
Instead of doing this, we need to compile with the -g flag as shown below:

gcc -g hello.c -o hello 

gcc -g myprogram.c

*.Compiles myprogram.c with the debugging option (-g). You still get an a.out, but it contains debugging information that lets you use variables and function names inside GDB, rather than raw memory locations (not fun).

*. gdb a.out

Opens GDB with file a.out, but does not run the program. You’ll see a prompt (gdb) - all examples are from this prompt.

q).Hey! gdb a.out is not working for me, How to install gdb?
*.
If you dont have gdb installed in your machine.
$ gdb a.out 
bash: gdb: command not found

Install gdb in below way:
$ sudo apt-get install gdb
Reading package lists... Done
Building dependency tree       
Reading state information... Done
...

Features:
---------
*.GDB offers extensive facilities for tracing and altering the  
  execution of computer programs. 
*.The user can monitor and modify the values of programs'
  internal variables, and even call functions independently of
  the program's normal behavior.
*.Since version 7.0, support for "reversible debugging" —
  allowing a debugging session to step backward, 
  much like rewinding a crashed program to see what happened — is
  available.

some usefull gdb stuff:
b main - Puts a breakpoint at the beginning of the program
b - Puts a breakpoint at the current line
b N - Puts a breakpoint at line N
b +N - Puts a breakpoint N lines down from the current line
b fn - Puts a breakpoint at the beginning of function "fn"
d N - Deletes breakpoint number N
info break - list breakpoints
r - Runs the program until a breakpoint or error
c - Continues running the program until the next breakpoint or 
    error
f - Runs until the current function is finished
s - Runs the next line of the program
s N - Runs the next N lines of the program
n - Like s, but it does not step into functions
u N - Runs until you get N lines in front of the current line
p var - Prints the current value of the variable "var"
bt - Prints a stack trace
u - Goes up a level in the stack
d - Goes down a level in the stack
q - Quits gdb


print:
------

*.Amazing! print is a built-in gdb command that prints the evaluation of a C expression. If you’re unsure of what a gdb command does, try running "help <name-of-the-command>" at the gdb prompt.

*.
 print x

Prints current value of variable x. Being able to use the original variable names is why the (-g) flag is needed; programs compiled regularly have this information removed.

gdb version 


Example code:
example code throughout this page:
hello.c
1 #include <stdio.h>
2
3 int add(int a, int b) {
4    printf("I am in add function\n");
5    return a+b;
6 }
7 int main()
8 {
9     int a; 
10    char *p = "I am in Text-Section";
11    add(2,3);
12    return 0;
13 }
run:
----

command line argument:
----------------------
*.(gdb) run arg1 arg2

*.
(gdb) r
(gdb) r arg1 arg2
(gdb) r < file1

three ways to run “a.out”, loaded previously. You can run it directly (r), pass arguments (r arg1 arg2), or feed in a file. You will usually set breakpoints before running.

(gdb)
(gdb) run 
Starting program: /home/a.out gcc -g hello.c

Breakpoint 2, main () at main.c:12
12      {
(gdb)
list:
-----
l
l 50
l myfunction

Lists 10 lines of source code for current line (l), a specific line (l 50), or for a function (l myfunction).
Breakpoint 1, main () at main.c:8
8       {
(gdb) list
3       int add(int a, int b) {
4           printf("I am in add function\n");
5           return a+b;
6       }
7       int main()
8       {
9           int a; 
10          char *p = "I am in Text-Section";
11          add(2,3);
12          return 0;
(gdb) 




*.next
Runs the program until next line, then pauses. If the current line is a function, it executes the entire function, then pauses. next is good for walking through your code quickly.

n or next , either way we can use. may be i am bit lazy person, that's why the reason i am using n in place of next, pls don't mind.
Breakpoint 1, main () at main.c:8
8       {
(gdb) next
10          char *p = "I am in Text-Section";
(gdb) next
11          add(2,3);
(gdb) n
I am in add function
12          return 0;
(gdb) 
*.step
Runs the next instruction, not line. If the current instruction is setting a variable, it is the same as next. If it’s a function, it will jump into the function, execute the first statement, then pause. step is good for diving into the details of your code.

s or step
Breakpoint 1, main () at main.c:8
8       {
(gdb) list 
3       int add(int a, int b) {
4           printf("I am in add function\n");
5           return a+b;
6       }
7       int main()
8       {
9           int a; 
10          char *p = "I am in Text-Section";
11          a = add(2,3);
12          return 0;
(gdb) 

Breakpoint 1, main () at main.c:8
8       {
(gdb) n
10          char *p = "I am in Text-Section";
(gdb) n
11          add(2,3);
(gdb) step
add (a=21845, b=1431654816) at main.c:3
3       int add(int a, int b) {
(gdb) n
4           printf("I am in add function\n");
(gdb) n
I am in add function
5           return a+b;
(gdb) n
6       }
(gdb) n
main () at main.c:12
12          return 0;
(gdb) 
break:
------
*.
(gdb) b 45
(gdb) b myfunction

(gdb) break main
(gdb) break add
(gdb) b sub
Sets a breakpoint at line 45, or at myfunction/main/add/sub. The program will pause when it reaches the breakpoint.


q).great! What if i forget where breakpoint is set?
*. Don't worry, use info break

q).how to delete a particular break point ?
ans).
*.
NOTE: if we give just r or run without any break, the program will invoke and exit, we left with no control to user to inspect the data inside of invoked program or running process
(gdb) r
Starting program: /home/a.out gcc -g 19_08_22.c
I am in add function
[Inferior 1 (process 347) exited normally]

NOTE: use break main, which helps us to paused at main/myfunction for inspection. :)
(gdb) break main 
Breakpoint 1 at 0x555555555171: file main.c, line 8.
(gdb) r
Starting program: /home/a.out gcc -g 19_08_22.c

Breakpoint 1, main () at main.c:8
8       {
(gdb) n
10          char *p = "I am in Text-Section";
(gdb) n
11          add(2,3);
(gdb) info break
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000555555555171 in main at main.c:8
        breakpoint already hit 1 time
(gdb) 
display:
--------
*.you can display them, but only if the variable is currently in scope. Each time you step the code, the value of the variable will be displayed (if it's in scope).
*Constantly displays the value of variable x, which is shown after every step or pause. Useful if you are constantly checking for a certain value.

q).How to show the current instruction when single-stepping instructions?
ans).
*.
(gdb) display/i $pc
Breakpoint 1, main () at main.c:8
8       {
(gdb) display p 
1: p = 0x0
(gdb) n
10          char *p = "I am in Text-Section";
1: p = 0x0
(gdb) n
11          add(2,3);
1: p = 0x555555556019 "I am in Text-Section"
(gdb) n
I am in add function
12          return 0;
1: p = 0x555555556019 "I am in Text-Section"
(gdb) n
13      }
1: p = 0x555555556019 "I am in Text-Section"
(gdb) n
__libc_start_main (main=0x555555555171 <main>, argc=4, argv=0x7fffffffeca8, 
    init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, 
    stack_end=0x7fffffffec98) at ../csu/libc-start.c:342
342     ../csu/libc-start.c: No such file or directory.
(gdb) 
undisplay:
----------
*.Removes the constant display of a variable displayed by display command.
Breakpoint 1, main () at main.c:8
8       {
(gdb) list 
3       int add(int a, int b) {
4           printf("I am in add function\n");
5           return a+b;
6       }
7       int main()
8       {
9           int a; 
10          char *p = "I am in Text-Section";
11          a = add(2,3);
12          return 0;


(gdb) display p 
1: p = 0x0
(gdb) n
10          char *p = "I am in Text-Section";
1: p = 0x0
(gdb) n
11          add(2,3);
1: p = 0x555555556019 "I am in Text-Section"
(gdb) undisplay 1
(gdb) n
I am in add function
12          return 0;
(gdb) n
13      }
(gdb) n
__libc_start_main (main=0x555555555171 <main>, argc=4, argv=0x7fffffffec98, 
    init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, 
    stack_end=0x7fffffffec88) at ../csu/libc-start.c:342
342     ../csu/libc-start.c: No such file or directory.
(gdb) 
*.
continue

Resumes execution after being paused by a breakpoint/watchpoint. The program will continue until it hits the next breakpoint/watchpoint.
1  #include <stdio.h>
2 
3  int add(int a, int b) {
4     printf("I am in add function\n");
5     return a+b;
6  }
7   int main()
8  {
9     int a; 
10    char *p = "I am in Text-Section";
11    add(2,3);
12    return 0;
13 }

NOTE: If there is no breakpoint(s), continue command executes the process which attached to the gdb fully and exits smoothly.

Breakpoint 1, main () at main.c:8
8       {
(gdb) continue
Continuing.
I am in add function
[Inferior 1 (process 332) exited normally]
(gdb) r
Starting program: /home/a.out gcc -g 19_08_22.c


NOTE: Continue executes all instructions unless there is breakpoint.
CASE 2:
-------
Breakpoint 1, main () at main.c:8
8       {
(gdb) b add
Breakpoint 2 at 0x555555555149: file main.c, line 3.
(gdb) c
Continuing.

Breakpoint 2, add (a=21845, b=1431654816) at main.c:3
3       int add(int a, int b) {
(gdb) n
4           printf("I am in add function\n");
(gdb) c
Continuing.
I am in add function
[Inferior 1 (process 336) exited normally]
(gdb) 
finish:
-------
*.To exit the current function and return to the calling function, use the finish command.
*.Finishes executing the current function, then pause (also called step out). Useful if you accidentally stepped into a function.
Breakpoint 1, main () at main.c:8
8       {
(gdb) n
10          char *p = "I am in Text-Section";
(gdb) n
11          add(2,3);
(gdb) s
add (a=21845, b=1431654816) at main.c:3
3       int add(int a, int b) {
(gdb) fin
Run till exit from #0  add (a=21845, b=1431654816) at main.c:3
I am in add function
main () at main.c:12
12          return 0;
Value returned is $1 = 5
(gdb) where
#0  main () at main.c:12
(gdb) n
13      }
(gdb) 
bt
---
Backtraces or prints the current function stack to show where you are in the current 
program. If main calls function a(), which calls b(), which calls c(), the backtrace is

0 c() <= current location 
1 b() 
2 a() 
3 main() 

up
down
Move to the next frame up or down in the function stack. If you are in c(), you can move to b or a to examine local variables.

return
Returns from current function.


Breakpoint 1, main () at main.c:8
8       {
(gdb) n
10          char *p = "I am in Text-Section";
(gdb) n
11          add(2,3);
(gdb) s
add (a=21845, b=1431654816) at main.c:3
3       int add(int a, int b) {
(gdb) n
4           printf("I am in add function\n");
(gdb) bt
#0  add (a=2, b=3) at main.c:4
#1  0x0000555555555197 in main () at main.c:11
(gdb) 
set:
----
*.(gdb) p head
$3 = (sll_t **) 0x7fffffffdf08
(gdb) set (head = 0)
(gdb) p head
$4 = (sll_t **) 0x0

set:
----
*.(gdb) p head
$3 = (sll_t **) 0x7fffffffdf08
(gdb) set (head = 0)
(gdb) p head
$4 = (sll_t **) 0x0
code