Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Introduction to Debuggers<br />The first bug - documented by Grace Hopper<br />
Introduction<br />
# who am i<br />Saumil Shah<br />CEO Net-square.<br />Hacker, Speaker, Trainer, Author.<br />M.S. Computer Science<br />Pu...
Preview<br />
Debuggers<br />
What is a debugger?<br />
What is a debugger?<br />A program used for debugging other programs or process. It provides...<br />
What is a debugger?<br />A program used for debugging other programs or process. It provides...<br />Fine grained control ...
A debugger lets you...<br />
Popular debuggers<br />gdb<br />windbg<br />
Working with programs<br />
A debugging example<br />
crash1.c<br />int main(int argc, char *argv[])<br />{<br />   int number;<br />   int *pointer;<br />   number = atoi(argv...
What does crash1.c do?<br />
What does crash1.c do?<br />crash1 takes the first command line argument and converts it to an integer<br />
What does crash1.c do?<br />crash1 takes the first command line argument and converts it to an integer<br />It then assign...
What does crash1.c do?<br />crash1 takes the first command line argument and converts it to an integer<br />It then assign...
Using gdb<br />
gdb<br />We shall debug crash1.c using gdb.<br />
gdb<br />We shall debug crash1.c using gdb.<br />gdb is a command line debugger.<br />
gdb<br />We shall debug crash1.c using gdb.<br />gdb is a command line debugger.<br />It is very unfriendly at first...<br...
Compiling crash1.c<br />Before we debug crash1.c, we need to compile it.<br />We shall then run crash1 from within gdb its...
Compile crash1.c and load it using gdb<br />$ gcc crash1.c -o crash1<br />
Compile crash1.c and load it using gdb<br />$ gcc crash1.c -o crash1<br />$ gdb crash1<br />GNU gdb (GDB) 7.2<br />Copyrig...
Now run it...<br />
Now run it...<br />...with no command line arguments.<br />
Now run it...<br />...with no command line arguments.<br />(gdb) run<br />Starting program: /home/user0/crash1 <br />Progr...
Now run it...<br />...with no command line arguments.<br />(gdb) run<br />Starting program: /home/user0/crash1 <br />Progr...
Now run it...<br />...with no command line arguments.<br />(gdb) run<br />Starting program: /home/user0/crash1 <br />Progr...
Now run it...<br />...with no command line arguments.<br />(gdb) run<br />Starting program: /home/user0/crash1 <br />Progr...
Use gdb command "backtrace"<br />
Use gdb command "backtrace"<br />It tries to reconstruct frames on the stack.<br />We can find out the sequence of functio...
Use gdb command "backtrace"<br />It tries to reconstruct frames on the stack.<br />We can find out the sequence of functio...
Use gdb command "backtrace"<br />It tries to reconstruct frames on the stack.<br />We can find out the sequence of functio...
Use gdb command "backtrace"<br />It tries to reconstruct frames on the stack.<br />We can find out the sequence of functio...
"x" to examine memory<br />
"x" to examine memory<br />(gdb) x/10i $eip<br />=> 0x40044c2e: movzx  ecx,BYTE PTR [edi]<br />   0x40044c31: mov    eax,D...
"x" to examine memory<br />(gdb) x/10i $eip<br />=> 0x40044c2e: movzx  ecx,BYTE PTR [edi]<br />   0x40044c31: mov    eax,D...
"x" to examine memory<br />(gdb) x/10i $eip<br />=> 0x40044c2e: movzx  ecx,BYTE PTR [edi]<br />   0x40044c31: mov    eax,D...
"x" - Examine Memory<br />
Where did the fault occur?<br />
Where did the fault occur?<br />Let us see the faulting instruction again.<br />
Where did the fault occur?<br />Let us see the faulting instruction again.<br />(gdb) x/10i $eip<br />=> 0x40044c2e: movzx...
Where did the fault occur?<br />Let us see the faulting instruction again.<br />(gdb) x/10i $eip<br />=> 0x40044c2e: movzx...
Where did the fault occur?<br />Let us see the faulting instruction again.<br />(gdb) x/10i $eip<br />=> 0x40044c2e: movzx...
Where did the fault occur?<br />Let us see the faulting instruction again.<br />(gdb) x/10i $eip<br />=> 0x40044c2e: movzx...
Use the "info registers" command.<br />
Use the "info registers" command.<br />(gdb) info registers<br />eax            0x40136660	0x40136660<br />ecx            ...
Use the "info registers" command.<br />(gdb) info registers<br />eax            0x40136660	0x40136660<br />ecx            ...
Use the "info registers" command.<br />(gdb) info registers<br />eax            0x40136660	0x40136660<br />ecx            ...
Let us try and inspect local variables and arguments, if any.<br />
Let us try and inspect local variables and arguments, if any.<br />Use the "info locals" and "info args" commands.<br />
Let us try and inspect local variables and arguments, if any.<br />Use the "info locals" and "info args" commands.<br />(g...
Let us try and inspect local variables and arguments, if any.<br />Use the "info locals" and "info args" commands.<br />(g...
Let us try and inspect local variables and arguments, if any.<br />Use the "info locals" and "info args" commands.<br />(g...
Let us try and inspect local variables and arguments, if any.<br />Use the "info locals" and "info args" commands.<br />(g...
Quit the debugger<br />(gdb) q<br />
Quit the debugger<br />(gdb) q<br />Recompile with debugging information enabled.<br />$ gcc -g crash1.c -o crash1<br />
Quit the debugger<br />(gdb) q<br />Recompile with debugging information enabled.<br />$ gcc -g crash1.c -o crash1<br />Th...
Load crash1 in gdb again<br />
Load crash1 in gdb again<br />$ gdb crash1<br />GNU gdb (GDB) 7.2<br />Copyright (C) 2010 Free Software Foundation, Inc.<b...
Load crash1 in gdb again<br />$ gdb crash1<br />GNU gdb (GDB) 7.2<br />Copyright (C) 2010 Free Software Foundation, Inc.<b...
Use gdb's "list" command<br />
Use gdb's "list" command<br />(gdb) list<br />1	#include <stdio.h><br />2	<br />3	void printnum(int *x);<br />4	<br />5	in...
Use gdb's "list" command<br />(gdb) list<br />1	#include <stdio.h><br />2	<br />3	void printnum(int *x);<br />4	<br />5	in...
Use gdb's "list" command<br />(gdb) list<br />1	#include <stdio.h><br />2	<br />3	void printnum(int *x);<br />4	<br />5	in...
Recap<br />We know that the program crashed when executing atoi(argv[1]).<br />
Recap<br />We know that the program crashed when executing atoi(argv[1]).<br />We shall now set a breakpoint at the statem...
Recap<br />We know that the program crashed when executing atoi(argv[1]).<br />We shall now set a breakpoint at the statem...
Use gdb's "break" command to set a breakpoint.<br />
Use gdb's "break" command to set a breakpoint.<br />(gdb) break 10<br />Breakpoint 1 at 0x804837c: file crash1.c, line 10....
Use gdb's "break" command to set a breakpoint.<br />(gdb) break 10<br />Breakpoint 1 at 0x804837c: file crash1.c, line 10....
Use gdb's "break" command to set a breakpoint.<br />(gdb) break 10<br />Breakpoint 1 at 0x804837c: file crash1.c, line 10....
Use gdb's "break" command to set a breakpoint.<br />(gdb) break 10<br />Breakpoint 1 at 0x804837c: file crash1.c, line 10....
Use gdb's "break" command to set a breakpoint.<br />(gdb) break 10<br />Breakpoint 1 at 0x804837c: file crash1.c, line 10....
gdb's "print" command lets us inspect variables.<br />
gdb's "print" command lets us inspect variables.<br />(gdb) print argv[1]<br />$1 = 0x0<br />
gdb's "print" command lets us inspect variables.<br />(gdb) print argv[1]<br />$1 = 0x0<br />argv[1] is the culprit NULL p...
gdb's "print" command lets us inspect variables.<br />(gdb) print argv[1]<br />$1 = 0x0<br />argv[1] is the culprit NULL p...
gdb's "print" command lets us inspect variables.<br />(gdb) print argv[1]<br />$1 = 0x0<br />argv[1] is the culprit NULL p...
gdb's "print" command lets us inspect variables.<br />(gdb) print argv[1]<br />$1 = 0x0<br />argv[1] is the culprit NULL p...
Bug #1 - Null pointer<br />To fix this problem the programmer needs to check the number of command line arguments before u...
Bug #1 - Null pointer<br />To fix this problem the programmer needs to check the number of command line arguments before u...
Bug #1 - Null pointer<br />To fix this problem the programmer needs to check the number of command line arguments before u...
Load crash1 in gdb again.<br />$ gdb crash1<br />GNU gdb (GDB) 7.2<br />...<br />Reading symbols from /home/user0/crash1.....
Load crash1 in gdb again.<br />$ gdb crash1<br />GNU gdb (GDB) 7.2<br />...<br />Reading symbols from /home/user0/crash1.....
Load crash1 in gdb again.<br />$ gdb crash1<br />GNU gdb (GDB) 7.2<br />...<br />Reading symbols from /home/user0/crash1.....
What do we do now?<br />
What do we do now?<br />I thought I asked the questions!<br />
What do we do now?<br />I thought I asked the questions!<br />We see where we crashed by examining frames from the stack. ...
What do we do now?<br />I thought I asked the questions!<br />We see where we crashed by examining frames from the stack. ...
What do we do now?<br />I thought I asked the questions!<br />We see where we crashed by examining frames from the stack. ...
What do we do now?<br />I thought I asked the questions!<br />We see where we crashed by examining frames from the stack. ...
That's right. x is an integer pointer, set to 0xff.<br />
That's right. x is an integer pointer, set to 0xff.<br />So it points to memory address 0x000000ff?<br />
That's right. x is an integer pointer, set to 0xff.<br />So it points to memory address 0x000000ff?<br />Yes. This memory ...
That's right. x is an integer pointer, set to 0xff.<br />So it points to memory address 0x000000ff?<br />Yes. This memory ...
That's right. x is an integer pointer, set to 0xff.<br />So it points to memory address 0x000000ff?<br />Yes. This memory ...
That's right. x is an integer pointer, set to 0xff.<br />So it points to memory address 0x000000ff?<br />Yes. This memory ...
gdb's "frame <n>" command lets you switch context to other frames.<br />
gdb's "frame <n>" command lets you switch context to other frames.<br />(gdb) frame 1<br />#1  0x080483a3 in main (argc=0x...
gdb's "frame <n>" command lets you switch context to other frames.<br />(gdb) frame 1<br />#1  0x080483a3 in main (argc=0x...
gdb's "frame <n>" command lets you switch context to other frames.<br />(gdb) frame 1<br />#1  0x080483a3 in main (argc=0x...
gdb's "frame <n>" command lets you switch context to other frames.<br />(gdb) frame 1<br />#1  0x080483a3 in main (argc=0x...
gdb's "frame <n>" command lets you switch context to other frames.<br />(gdb) frame 1<br />#1  0x080483a3 in main (argc=0x...
Absolutely correct. What should we do instead?<br />
Absolutely correct. What should we do instead?<br />Make the pointer POINT to the number.<br />
Absolutely correct. What should we do instead?<br />Make the pointer POINT to the number.<br />Set the pointer's value to ...
Bug #2 - Pointer mess-up<br />The faulting statement is:<br />pointer = number;<br />
Bug #2 - Pointer mess-up<br />The faulting statement is:<br />pointer = number;<br />Instead it should be:<br />pointer = ...
Bug #2 - Pointer mess-up<br />The faulting statement is:<br />pointer = number;<br />Instead it should be:<br />pointer = ...
(gdb) frame 0<br />
(gdb) frame 0<br />(gdb) x/10i $eip<br />=> 0x80483b4 <printnum+12>:	push   DWORD PTR [eax]<br />   0x80483b6 <printnum+14...
(gdb) frame 0<br />(gdb) x/10i $eip<br />=> 0x80483b4 <printnum+12>:	push   DWORD PTR [eax]<br />   0x80483b6 <printnum+14...
(gdb) frame 0<br />(gdb) x/10i $eip<br />=> 0x80483b4 <printnum+12>:	push   DWORD PTR [eax]<br />   0x80483b6 <printnum+14...
There are two PUSHes. The first pushes the contents at address EAX onto the stack.<br />
There are two PUSHes. The first pushes the contents at address EAX onto the stack.<br />EAX stores the address of the poin...
There are two PUSHes. The first pushes the contents at address EAX onto the stack.<br />EAX stores the address of the poin...
There are two PUSHes. The first pushes the contents at address EAX onto the stack.<br />EAX stores the address of the poin...
There are two PUSHes. The first pushes the contents at address EAX onto the stack.<br />EAX stores the address of the poin...
There are two PUSHes. The first pushes the contents at address EAX onto the stack.<br />EAX stores the address of the poin...
printf()<br />printf("The number supplied is %d", *x);<br />
printf()<br />printf("The number supplied is %d", *x);<br /> push   DWORD PTR [eax]<br />
printf()<br />printf("The number supplied is %d", *x);<br /> push   DWORD PTR [eax]<br /> push   0x8048488<br />
printf()<br />printf("The number supplied is %d", *x);<br /> push   DWORD PTR [eax]<br /> push   0x8048488<br /> call   0x...
printf()<br />printf("The number supplied is %d", *x);<br /> push   DWORD PTR [eax]<br /> push   0x8048488<br /> call   0x...
So where does address 0x08048488 point to?<br />
So where does address 0x08048488 point to?<br />It should point to the string:<br />"The number supplied is %d"<br />
So where does address 0x08048488 point to?<br />It should point to the string:<br />"The number supplied is %d"<br />Let u...
So where does address 0x08048488 point to?<br />It should point to the string:<br />"The number supplied is %d"<br />Let u...
Disassembling printnum()<br />To wrap this up, let us dive into the assembly code of function printnum().<br />We shall ma...
Use the "disassemble" command<br />
Use the "disassemble" command<br />(gdb) disassemble printnum<br />Dump of assembler code for function printnum:<br />   0...
Use the "disassemble" command<br />(gdb) disassemble printnum<br />Dump of assembler code for function printnum:<br />   0...
printnum() disassembly<br />Prologue<br />  push   ebp<br />  mov    ebp,esp<br />  sub    esp,0x8<br />  sub    esp,0x8<b...
printnum() disassembly<br />Prologue<br />  push   ebp<br />  mov    ebp,esp<br />  sub    esp,0x8<br />  sub    esp,0x8<b...
printnum() disassembly<br />Prologue<br />  push   ebp<br />  mov    ebp,esp<br />  sub    esp,0x8<br />  sub    esp,0x8<b...
Before printnum() is called<br />  push  ebp<br />  mov   ebp,esp<br />  sub   esp,0x8<br />  sub   esp,0x8<br />  mov   e...
Before printnum() is called<br />> push  ebp<br />  mov   ebp,esp<br />  sub   esp,0x8<br />  sub   esp,0x8<br />  mov   e...
Prologue<br />push  ebp<br />> mov   ebp,esp<br />  sub   esp,0x8<br />  sub   esp,0x8<br />  mov   eax,DWORD PTR [ebp+0x8...
Prologue<br />push  ebp<br />mov   ebp,esp<br />> sub   esp,0x8<br />  sub   esp,0x8<br />  mov   eax,DWORD PTR [ebp+0x8]<...
Prologue<br />push  ebp<br />mov   ebp,esp<br />  sub   esp,0x8<br />  sub   esp,0x8<br />> mov   eax,DWORD PTR [ebp+0x8]<...
Body<br />push  ebp<br />mov   ebp,esp<br />  sub   esp,0x8<br />  sub   esp,0x8<br />mov   eax,DWORD PTR [ebp+0x8]<br />>...
Segmentation Fault!<br />push  ebp<br />mov   ebp,esp<br />  sub   esp,0x8<br />  sub   esp,0x8<br />mov   eax,DWORD PTR [...
Segmentation Fault!<br />push  ebp<br />mov   ebp,esp<br />  sub   esp,0x8<br />  sub   esp,0x8<br />mov   eax,DWORD PTR [...
Examine stack memory and registers<br />
Examine stack memory and registers<br />(gdb) x/16xw $esp<br />0xbffff938: 0x0000000a 0x00000000 0x40042550 0x40012df8<br ...
Examine stack memory and registers<br />(gdb) x/16xw $esp<br />0xbffff938: 0x0000000a 0x00000000 0x40042550 0x40012df8<br ...
Examine stack memory and registers<br />(gdb) x/16xw $esp<br />0xbffff938: 0x0000000a 0x00000000 0x40042550 0x40012df8<br ...
Recap<br />We have seen how to analyze crashes and identify causes of errors.<br />We also saw a lot of gdb commands and w...
Summary of gdb commands<br />
A few gdb commands<br />
A few more gdb commands<br />
Review<br />
END<br />photo: Brian Searle - bit.ly/fpcxY9<br />
Upcoming SlideShare
Loading in …5
×

of

Introduction to Debuggers Slide 1 Introduction to Debuggers Slide 2 Introduction to Debuggers Slide 3 Introduction to Debuggers Slide 4 Introduction to Debuggers Slide 5 Introduction to Debuggers Slide 6 Introduction to Debuggers Slide 7 Introduction to Debuggers Slide 8 Introduction to Debuggers Slide 9 Introduction to Debuggers Slide 10 Introduction to Debuggers Slide 11 Introduction to Debuggers Slide 12 Introduction to Debuggers Slide 13 Introduction to Debuggers Slide 14 Introduction to Debuggers Slide 15 Introduction to Debuggers Slide 16 Introduction to Debuggers Slide 17 Introduction to Debuggers Slide 18 Introduction to Debuggers Slide 19 Introduction to Debuggers Slide 20 Introduction to Debuggers Slide 21 Introduction to Debuggers Slide 22 Introduction to Debuggers Slide 23 Introduction to Debuggers Slide 24 Introduction to Debuggers Slide 25 Introduction to Debuggers Slide 26 Introduction to Debuggers Slide 27 Introduction to Debuggers Slide 28 Introduction to Debuggers Slide 29 Introduction to Debuggers Slide 30 Introduction to Debuggers Slide 31 Introduction to Debuggers Slide 32 Introduction to Debuggers Slide 33 Introduction to Debuggers Slide 34 Introduction to Debuggers Slide 35 Introduction to Debuggers Slide 36 Introduction to Debuggers Slide 37 Introduction to Debuggers Slide 38 Introduction to Debuggers Slide 39 Introduction to Debuggers Slide 40 Introduction to Debuggers Slide 41 Introduction to Debuggers Slide 42 Introduction to Debuggers Slide 43 Introduction to Debuggers Slide 44 Introduction to Debuggers Slide 45 Introduction to Debuggers Slide 46 Introduction to Debuggers Slide 47 Introduction to Debuggers Slide 48 Introduction to Debuggers Slide 49 Introduction to Debuggers Slide 50 Introduction to Debuggers Slide 51 Introduction to Debuggers Slide 52 Introduction to Debuggers Slide 53 Introduction to Debuggers Slide 54 Introduction to Debuggers Slide 55 Introduction to Debuggers Slide 56 Introduction to Debuggers Slide 57 Introduction to Debuggers Slide 58 Introduction to Debuggers Slide 59 Introduction to Debuggers Slide 60 Introduction to Debuggers Slide 61 Introduction to Debuggers Slide 62 Introduction to Debuggers Slide 63 Introduction to Debuggers Slide 64 Introduction to Debuggers Slide 65 Introduction to Debuggers Slide 66 Introduction to Debuggers Slide 67 Introduction to Debuggers Slide 68 Introduction to Debuggers Slide 69 Introduction to Debuggers Slide 70 Introduction to Debuggers Slide 71 Introduction to Debuggers Slide 72 Introduction to Debuggers Slide 73 Introduction to Debuggers Slide 74 Introduction to Debuggers Slide 75 Introduction to Debuggers Slide 76 Introduction to Debuggers Slide 77 Introduction to Debuggers Slide 78 Introduction to Debuggers Slide 79 Introduction to Debuggers Slide 80 Introduction to Debuggers Slide 81 Introduction to Debuggers Slide 82 Introduction to Debuggers Slide 83 Introduction to Debuggers Slide 84 Introduction to Debuggers Slide 85 Introduction to Debuggers Slide 86 Introduction to Debuggers Slide 87 Introduction to Debuggers Slide 88 Introduction to Debuggers Slide 89 Introduction to Debuggers Slide 90 Introduction to Debuggers Slide 91 Introduction to Debuggers Slide 92 Introduction to Debuggers Slide 93 Introduction to Debuggers Slide 94 Introduction to Debuggers Slide 95 Introduction to Debuggers Slide 96 Introduction to Debuggers Slide 97 Introduction to Debuggers Slide 98 Introduction to Debuggers Slide 99 Introduction to Debuggers Slide 100 Introduction to Debuggers Slide 101 Introduction to Debuggers Slide 102 Introduction to Debuggers Slide 103 Introduction to Debuggers Slide 104 Introduction to Debuggers Slide 105 Introduction to Debuggers Slide 106 Introduction to Debuggers Slide 107 Introduction to Debuggers Slide 108 Introduction to Debuggers Slide 109 Introduction to Debuggers Slide 110 Introduction to Debuggers Slide 111 Introduction to Debuggers Slide 112 Introduction to Debuggers Slide 113 Introduction to Debuggers Slide 114 Introduction to Debuggers Slide 115 Introduction to Debuggers Slide 116 Introduction to Debuggers Slide 117 Introduction to Debuggers Slide 118 Introduction to Debuggers Slide 119 Introduction to Debuggers Slide 120 Introduction to Debuggers Slide 121 Introduction to Debuggers Slide 122 Introduction to Debuggers Slide 123 Introduction to Debuggers Slide 124 Introduction to Debuggers Slide 125 Introduction to Debuggers Slide 126 Introduction to Debuggers Slide 127 Introduction to Debuggers Slide 128 Introduction to Debuggers Slide 129 Introduction to Debuggers Slide 130 Introduction to Debuggers Slide 131 Introduction to Debuggers Slide 132 Introduction to Debuggers Slide 133 Introduction to Debuggers Slide 134 Introduction to Debuggers Slide 135 Introduction to Debuggers Slide 136 Introduction to Debuggers Slide 137 Introduction to Debuggers Slide 138 Introduction to Debuggers Slide 139 Introduction to Debuggers Slide 140 Introduction to Debuggers Slide 141 Introduction to Debuggers Slide 142 Introduction to Debuggers Slide 143 Introduction to Debuggers Slide 144 Introduction to Debuggers Slide 145 Introduction to Debuggers Slide 146 Introduction to Debuggers Slide 147 Introduction to Debuggers Slide 148 Introduction to Debuggers Slide 149 Introduction to Debuggers Slide 150 Introduction to Debuggers Slide 151 Introduction to Debuggers Slide 152 Introduction to Debuggers Slide 153 Introduction to Debuggers Slide 154 Introduction to Debuggers Slide 155 Introduction to Debuggers Slide 156
Upcoming SlideShare
How Functions Work
Next

45 Likes

Share

Introduction to Debuggers

A quick tutorial on what debuggers are and how to use them. We present a debugging example using GDB. At the end of this tutorial, you will be able to work your way through a crash and analyze the cause of the error responsible for the crash.

Related Books

Free with a 30 day trial from Scribd

See all

Introduction to Debuggers

  1. 1. Introduction to Debuggers<br />The first bug - documented by Grace Hopper<br />
  2. 2. Introduction<br />
  3. 3. # who am i<br />Saumil Shah<br />CEO Net-square.<br />Hacker, Speaker, Trainer, Author.<br />M.S. Computer Science<br />Purdue University.<br />Google: "saumil"<br />LinkedIn: saumilshah<br />
  4. 4. Preview<br />
  5. 5. Debuggers<br />
  6. 6. What is a debugger?<br />
  7. 7. What is a debugger?<br />A program used for debugging other programs or process. It provides...<br />
  8. 8. What is a debugger?<br />A program used for debugging other programs or process. It provides...<br />Fine grained control over process execution<br />Inspection of CPU state<br />Inspection of process memory<br />
  9. 9. A debugger lets you...<br />
  10. 10. Popular debuggers<br />gdb<br />windbg<br />
  11. 11. Working with programs<br />
  12. 12.
  13. 13. A debugging example<br />
  14. 14. crash1.c<br />int main(int argc, char *argv[])<br />{<br /> int number;<br /> int *pointer;<br /> number = atoi(argv[1]);<br /> pointer = number;<br /> printnum(pointer);<br />}<br />void printnum(int *x)<br />{<br /> printf("The number supplied is %d", *x);<br />}<br />
  15. 15. What does crash1.c do?<br />
  16. 16. What does crash1.c do?<br />crash1 takes the first command line argument and converts it to an integer<br />
  17. 17. What does crash1.c do?<br />crash1 takes the first command line argument and converts it to an integer<br />It then assigns a pointer to this integer...<br />...and passes it to a function - printnum()<br />
  18. 18. What does crash1.c do?<br />crash1 takes the first command line argument and converts it to an integer<br />It then assigns a pointer to this integer...<br />...and passes it to a function - printnum()<br />There are TWO bugs in this program<br />Can you spot them?<br />
  19. 19. Using gdb<br />
  20. 20. gdb<br />We shall debug crash1.c using gdb.<br />
  21. 21. gdb<br />We shall debug crash1.c using gdb.<br />gdb is a command line debugger.<br />
  22. 22. gdb<br />We shall debug crash1.c using gdb.<br />gdb is a command line debugger.<br />It is very unfriendly at first...<br />...but very powerful!<br />
  23. 23. Compiling crash1.c<br />Before we debug crash1.c, we need to compile it.<br />We shall then run crash1 from within gdb itself.<br />
  24. 24. Compile crash1.c and load it using gdb<br />$ gcc crash1.c -o crash1<br />
  25. 25. Compile crash1.c and load it using gdb<br />$ gcc crash1.c -o crash1<br />$ gdb crash1<br />GNU gdb (GDB) 7.2<br />Copyright (C) 2010 Free Software Foundation, Inc.<br />License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html><br />This is free software: you are free to change and redistribute it.<br />There is NO WARRANTY, to the extent permitted by law. Type "show copying"<br />and "show warranty" for details.<br />This GDB was configured as "i686-pc-linux-gnu".<br />For bug reporting instructions, please see:<br /><http://www.gnu.org/software/gdb/bugs/>...<br />Reading symbols from /home/user0/crash1...done.<br />(gdb)<br />
  26. 26. Now run it...<br />
  27. 27. Now run it...<br />...with no command line arguments.<br />
  28. 28. Now run it...<br />...with no command line arguments.<br />(gdb) run<br />Starting program: /home/user0/crash1 <br />Program received signal SIGSEGV, Segmentation fault.<br />0x40044c2e in __strtol_internal () from /lib/i686/libc.so.6<br />
  29. 29. Now run it...<br />...with no command line arguments.<br />(gdb) run<br />Starting program: /home/user0/crash1 <br />Program received signal SIGSEGV, Segmentation fault.<br />0x40044c2e in __strtol_internal () from /lib/i686/libc.so.6<br />The program crashes.<br />
  30. 30. Now run it...<br />...with no command line arguments.<br />(gdb) run<br />Starting program: /home/user0/crash1 <br />Program received signal SIGSEGV, Segmentation fault.<br />0x40044c2e in __strtol_internal () from /lib/i686/libc.so.6<br />The program crashes.<br />Where in the code did it crash?<br />
  31. 31. Now run it...<br />...with no command line arguments.<br />(gdb) run<br />Starting program: /home/user0/crash1 <br />Program received signal SIGSEGV, Segmentation fault.<br />0x40044c2e in __strtol_internal () from /lib/i686/libc.so.6<br />The program crashes.<br />Where in the code did it crash?<br />Let us find out where exactly it has crashed.<br />
  32. 32. Use gdb command "backtrace"<br />
  33. 33. Use gdb command "backtrace"<br />It tries to reconstruct frames on the stack.<br />We can find out the sequence of function calls at the time of the crash.<br />
  34. 34. Use gdb command "backtrace"<br />It tries to reconstruct frames on the stack.<br />We can find out the sequence of function calls at the time of the crash.<br />(gdb) backtrace<br />#0 0x40044c2e in __strtol_internal () from /lib/i686/libc.so.6<br />#1 0x40042579 in atoi () from /lib/i686/libc.so.6<br />#2 0x0804838c in main ()<br />
  35. 35. Use gdb command "backtrace"<br />It tries to reconstruct frames on the stack.<br />We can find out the sequence of function calls at the time of the crash.<br />(gdb) backtrace<br />#0 0x40044c2e in __strtol_internal () from /lib/i686/libc.so.6<br />#1 0x40042579 in atoi () from /lib/i686/libc.so.6<br />#2 0x0804838c in main ()<br />Looks like it crashed after calling atoi().<br />
  36. 36. Use gdb command "backtrace"<br />It tries to reconstruct frames on the stack.<br />We can find out the sequence of function calls at the time of the crash.<br />(gdb) backtrace<br />#0 0x40044c2e in __strtol_internal () from /lib/i686/libc.so.6<br />#1 0x40042579 in atoi () from /lib/i686/libc.so.6<br />#2 0x0804838c in main ()<br />Looks like it crashed after calling atoi().<br />That's right. Let us check out the instructions in the code where it has crashed. EIP points to the last instruction executed.<br />
  37. 37. "x" to examine memory<br />
  38. 38. "x" to examine memory<br />(gdb) x/10i $eip<br />=> 0x40044c2e: movzx ecx,BYTE PTR [edi]<br /> 0x40044c31: mov eax,DWORD PTR [esi]<br /> 0x40044c33: movsx edx,cl<br /> 0x40044c36: movzx eax,WORD PTR [eax+edx*2]<br /> 0x40044c3a: and eax,0x2000<br /> 0x40044c3f: test ax,ax<br />
  39. 39. "x" to examine memory<br />(gdb) x/10i $eip<br />=> 0x40044c2e: movzx ecx,BYTE PTR [edi]<br /> 0x40044c31: mov eax,DWORD PTR [esi]<br /> 0x40044c33: movsx edx,cl<br /> 0x40044c36: movzx eax,WORD PTR [eax+edx*2]<br /> 0x40044c3a: and eax,0x2000<br /> 0x40044c3f: test ax,ax<br />So what is x/10i ?<br />
  40. 40. "x" to examine memory<br />(gdb) x/10i $eip<br />=> 0x40044c2e: movzx ecx,BYTE PTR [edi]<br /> 0x40044c31: mov eax,DWORD PTR [esi]<br /> 0x40044c33: movsx edx,cl<br /> 0x40044c36: movzx eax,WORD PTR [eax+edx*2]<br /> 0x40044c3a: and eax,0x2000<br /> 0x40044c3f: test ax,ax<br />So what is x/10i ?<br />"x" displays memory contents in various formats. "i" is for instructions (disassembly). 10 is the count of instructions to disassemble.<br />Here are some more options for "x"<br />
  41. 41. "x" - Examine Memory<br />
  42. 42. Where did the fault occur?<br />
  43. 43. Where did the fault occur?<br />Let us see the faulting instruction again.<br />
  44. 44. Where did the fault occur?<br />Let us see the faulting instruction again.<br />(gdb) x/10i $eip<br />=> 0x40044c2e: movzx ecx,BYTE PTR [edi]<br />
  45. 45. Where did the fault occur?<br />Let us see the faulting instruction again.<br />(gdb) x/10i $eip<br />=> 0x40044c2e: movzx ecx,BYTE PTR [edi]<br />movzx ecx, byte ptr [edi] takes the byte at memory address stored within EDI and copies it into the ECX register.<br />
  46. 46. Where did the fault occur?<br />Let us see the faulting instruction again.<br />(gdb) x/10i $eip<br />=> 0x40044c2e: movzx ecx,BYTE PTR [edi]<br />movzx ecx, byte ptr [edi] takes the byte at memory address stored within EDI and copies it into the ECX register.<br />I see no apparent error here.<br />
  47. 47. Where did the fault occur?<br />Let us see the faulting instruction again.<br />(gdb) x/10i $eip<br />=> 0x40044c2e: movzx ecx,BYTE PTR [edi]<br />movzx ecx, byte ptr [edi] takes the byte at memory address stored within EDI and copies it into the ECX register.<br />I see no apparent error here.<br />It depends on where EDI points to. Let us inspect the registers.<br />
  48. 48. Use the "info registers" command.<br />
  49. 49. Use the "info registers" command.<br />(gdb) info registers<br />eax 0x40136660 0x40136660<br />ecx 0x0 0x0<br />edx 0x0 0x0<br />ebx 0x40148f50 0x40148f50<br />esp 0xbffff8d0 0xbffff8d0<br />ebp 0xbffff928 0xbffff928<br />esi 0x4014b8b8 0x4014b8b8<br />edi 0x0 0x0<br />eip 0x40044c2e 0x40044c2e <__strtol_internal+142><br />eflags 0x10206 [ PF IF RF ]<br />
  50. 50. Use the "info registers" command.<br />(gdb) info registers<br />eax 0x40136660 0x40136660<br />ecx 0x0 0x0<br />edx 0x0 0x0<br />ebx 0x40148f50 0x40148f50<br />esp 0xbffff8d0 0xbffff8d0<br />ebp 0xbffff928 0xbffff928<br />esi 0x4014b8b8 0x4014b8b8<br />edi 0x0 0x0<br />eip 0x40044c2e 0x40044c2e <__strtol_internal+142><br />eflags 0x10206 [ PF IF RF ]<br />I see that EDI is 0.<br />
  51. 51. Use the "info registers" command.<br />(gdb) info registers<br />eax 0x40136660 0x40136660<br />ecx 0x0 0x0<br />edx 0x0 0x0<br />ebx 0x40148f50 0x40148f50<br />esp 0xbffff8d0 0xbffff8d0<br />ebp 0xbffff928 0xbffff928<br />esi 0x4014b8b8 0x4014b8b8<br />edi 0x0 0x0<br />eip 0x40044c2e 0x40044c2e <__strtol_internal+142><br />eflags 0x10206 [ PF IF RF ]<br />I see that EDI is 0.<br />EDI is a NULL pointer. It points to non-existent memory. Hence the crash.<br />
  52. 52. Let us try and inspect local variables and arguments, if any.<br />
  53. 53. Let us try and inspect local variables and arguments, if any.<br />Use the "info locals" and "info args" commands.<br />
  54. 54. Let us try and inspect local variables and arguments, if any.<br />Use the "info locals" and "info args" commands.<br />(gdb) info locals <br />No symbol table info available.<br />(gdb) info args <br />No symbol table info available.<br />
  55. 55. Let us try and inspect local variables and arguments, if any.<br />Use the "info locals" and "info args" commands.<br />(gdb) info locals <br />No symbol table info available.<br />(gdb) info args <br />No symbol table info available.<br />What does this mean?<br />
  56. 56. Let us try and inspect local variables and arguments, if any.<br />Use the "info locals" and "info args" commands.<br />(gdb) info locals <br />No symbol table info available.<br />(gdb) info args <br />No symbol table info available.<br />What does this mean?<br />The compiled binary does not contain debugging information to resolve symbols. <br />
  57. 57. Let us try and inspect local variables and arguments, if any.<br />Use the "info locals" and "info args" commands.<br />(gdb) info locals <br />No symbol table info available.<br />(gdb) info args <br />No symbol table info available.<br />What does this mean?<br />The compiled binary does not contain debugging information to resolve symbols. <br />We need to compile the binary again, this time with proper debugging information.<br />
  58. 58. Quit the debugger<br />(gdb) q<br />
  59. 59. Quit the debugger<br />(gdb) q<br />Recompile with debugging information enabled.<br />$ gcc -g crash1.c -o crash1<br />
  60. 60. Quit the debugger<br />(gdb) q<br />Recompile with debugging information enabled.<br />$ gcc -g crash1.c -o crash1<br />The "-g" flag tells the compiler to include symbolic debugging information in the compiled binary.<br />
  61. 61. Load crash1 in gdb again<br />
  62. 62. Load crash1 in gdb again<br />$ gdb crash1<br />GNU gdb (GDB) 7.2<br />Copyright (C) 2010 Free Software Foundation, Inc.<br />License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html><br />This is free software: you are free to change and redistribute it.<br />There is NO WARRANTY, to the extent permitted by law. Type "show copying"<br />and "show warranty" for details.<br />This GDB was configured as "i686-pc-linux-gnu".<br />For bug reporting instructions, please see:<br /><http://www.gnu.org/software/gdb/bugs/>...<br />Reading symbols from /home/user0/crash1...done.<br />(gdb)<br />
  63. 63. Load crash1 in gdb again<br />$ gdb crash1<br />GNU gdb (GDB) 7.2<br />Copyright (C) 2010 Free Software Foundation, Inc.<br />License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html><br />This is free software: you are free to change and redistribute it.<br />There is NO WARRANTY, to the extent permitted by law. Type "show copying"<br />and "show warranty" for details.<br />This GDB was configured as "i686-pc-linux-gnu".<br />For bug reporting instructions, please see:<br /><http://www.gnu.org/software/gdb/bugs/>...<br />Reading symbols from /home/user0/crash1...done.<br />(gdb)<br />Let us look at the program listing, which is now available from the debugging information. <br />
  64. 64. Use gdb's "list" command<br />
  65. 65. Use gdb's "list" command<br />(gdb) list<br />1 #include <stdio.h><br />2 <br />3 void printnum(int *x);<br />4 <br />5 int main(int argc, char *argv[])<br />6 {<br />7 int number;<br />8 int *pointer;<br />9 <br />10 number = atoi(argv[1]);<br />
  66. 66. Use gdb's "list" command<br />(gdb) list<br />1 #include <stdio.h><br />2 <br />3 void printnum(int *x);<br />4 <br />5 int main(int argc, char *argv[])<br />6 {<br />7 int number;<br />8 int *pointer;<br />9 <br />10 number = atoi(argv[1]);<br />But there are more than 10 lines in this program.<br />
  67. 67. Use gdb's "list" command<br />(gdb) list<br />1 #include <stdio.h><br />2 <br />3 void printnum(int *x);<br />4 <br />5 int main(int argc, char *argv[])<br />6 {<br />7 int number;<br />8 int *pointer;<br />9 <br />10 number = atoi(argv[1]);<br />But there are more than 10 lines in this program.<br />Press Enter on a blank gdb prompt to get another screenful of program listing.<br />
  68. 68. Recap<br />We know that the program crashed when executing atoi(argv[1]).<br />
  69. 69. Recap<br />We know that the program crashed when executing atoi(argv[1]).<br />We shall now set a breakpoint at the statement where atoi() is called.<br />
  70. 70. Recap<br />We know that the program crashed when executing atoi(argv[1]).<br />We shall now set a breakpoint at the statement where atoi() is called.<br />atoi() is called in line #10:<br />7 int number;<br />8 int *pointer;<br />9 <br />10 number = atoi(argv[1]);<br />
  71. 71. Use gdb's "break" command to set a breakpoint.<br />
  72. 72. Use gdb's "break" command to set a breakpoint.<br />(gdb) break 10<br />Breakpoint 1 at 0x804837c: file crash1.c, line 10.<br />
  73. 73. Use gdb's "break" command to set a breakpoint.<br />(gdb) break 10<br />Breakpoint 1 at 0x804837c: file crash1.c, line 10.<br />Now let us run the program.<br />
  74. 74. Use gdb's "break" command to set a breakpoint.<br />(gdb) break 10<br />Breakpoint 1 at 0x804837c: file crash1.c, line 10.<br />Now let us run the program.<br />(gdb) run<br />Starting program: /home/user0/crash1 <br />Breakpoint 1, main (argc=0x1, argv=0xbffff9b4) at crash1.c:10<br />10 number = atoi(argv[1]);<br />
  75. 75. Use gdb's "break" command to set a breakpoint.<br />(gdb) break 10<br />Breakpoint 1 at 0x804837c: file crash1.c, line 10.<br />Now let us run the program.<br />(gdb) run<br />Starting program: /home/user0/crash1 <br />Breakpoint 1, main (argc=0x1, argv=0xbffff9b4) at crash1.c:10<br />10 number = atoi(argv[1]);<br />Process execution is suspended when it reaches the breakpoint. Control is transferred to gdb.<br />
  76. 76. Use gdb's "break" command to set a breakpoint.<br />(gdb) break 10<br />Breakpoint 1 at 0x804837c: file crash1.c, line 10.<br />Now let us run the program.<br />(gdb) run<br />Starting program: /home/user0/crash1 <br />Breakpoint 1, main (argc=0x1, argv=0xbffff9b4) at crash1.c:10<br />10 number = atoi(argv[1]);<br />Process execution is suspended when it reaches the breakpoint. Control is transferred to gdb.<br />Let us now look at argv[1]. gdb will now allow us to inspect variables symbolically.<br />
  77. 77. gdb's "print" command lets us inspect variables.<br />
  78. 78. gdb's "print" command lets us inspect variables.<br />(gdb) print argv[1]<br />$1 = 0x0<br />
  79. 79. gdb's "print" command lets us inspect variables.<br />(gdb) print argv[1]<br />$1 = 0x0<br />argv[1] is the culprit NULL pointer! This is what gets loaded into the EDI register (remember?)<br />
  80. 80. gdb's "print" command lets us inspect variables.<br />(gdb) print argv[1]<br />$1 = 0x0<br />argv[1] is the culprit NULL pointer! This is what gets loaded into the EDI register (remember?)<br />Let us continue with the process execution.<br />
  81. 81. gdb's "print" command lets us inspect variables.<br />(gdb) print argv[1]<br />$1 = 0x0<br />argv[1] is the culprit NULL pointer! This is what gets loaded into the EDI register (remember?)<br />Let us continue with the process execution.<br />(gdb) continue<br />Continuing.<br />Program received signal SIGSEGV, Segmentation fault.<br />0x40044c2e in __strtol_internal () from /lib/i686/libc.so.6<br />
  82. 82. gdb's "print" command lets us inspect variables.<br />(gdb) print argv[1]<br />$1 = 0x0<br />argv[1] is the culprit NULL pointer! This is what gets loaded into the EDI register (remember?)<br />Let us continue with the process execution.<br />(gdb) continue<br />Continuing.<br />Program received signal SIGSEGV, Segmentation fault.<br />0x40044c2e in __strtol_internal () from /lib/i686/libc.so.6<br />As expected, here's the segmentation fault. Verify the value of EDI using "info registers" and the disassembly of the crash using "x/10i $eip"<br />
  83. 83. Bug #1 - Null pointer<br />To fix this problem the programmer needs to check the number of command line arguments before using argv[1] in the program.<br />
  84. 84. Bug #1 - Null pointer<br />To fix this problem the programmer needs to check the number of command line arguments before using argv[1] in the program.<br />For now, we shall run the program with a valid argv[1] supplied.<br />
  85. 85. Bug #1 - Null pointer<br />To fix this problem the programmer needs to check the number of command line arguments before using argv[1] in the program.<br />For now, we shall run the program with a valid argv[1] supplied.<br />On to bug #2.<br />Quit gdb and load crash1 again.<br />
  86. 86. Load crash1 in gdb again.<br />$ gdb crash1<br />GNU gdb (GDB) 7.2<br />...<br />Reading symbols from /home/user0/crash1...done.<br />(gdb)<br />
  87. 87. Load crash1 in gdb again.<br />$ gdb crash1<br />GNU gdb (GDB) 7.2<br />...<br />Reading symbols from /home/user0/crash1...done.<br />(gdb)<br />Run it with argument 1 as 255 (or any number)<br />(gdb) run 255<br />Starting program: /home/user0/crash1 255<br />Program received signal SIGSEGV, Segmentation fault.<br />0x080483b4 in printnum (x=0xff) at crash1.c:17<br />17 printf("The number supplied is %d", *x);<br />
  88. 88. Load crash1 in gdb again.<br />$ gdb crash1<br />GNU gdb (GDB) 7.2<br />...<br />Reading symbols from /home/user0/crash1...done.<br />(gdb)<br />Run it with argument 1 as 255 (or any number)<br />(gdb) run 255<br />Starting program: /home/user0/crash1 255<br />Program received signal SIGSEGV, Segmentation fault.<br />0x080483b4 in printnum (x=0xff) at crash1.c:17<br />17 printf("The number supplied is %d", *x);<br />Another segmentation fault. Another crash.<br />
  89. 89. What do we do now?<br />
  90. 90. What do we do now?<br />I thought I asked the questions!<br />
  91. 91. What do we do now?<br />I thought I asked the questions!<br />We see where we crashed by examining frames from the stack. The "backtrace" command.<br />(gdb) backtrace<br />#0 0x080483b4 in printnum (x=0xff) at crash1.c:17<br />#1 0x080483a3 in main (argc=0x2, argv=0xbffff9b4) at crash1.c:12<br />
  92. 92. What do we do now?<br />I thought I asked the questions!<br />We see where we crashed by examining frames from the stack. The "backtrace" command.<br />(gdb) backtrace<br />#0 0x080483b4 in printnum (x=0xff) at crash1.c:17<br />#1 0x080483a3 in main (argc=0x2, argv=0xbffff9b4) at crash1.c:12<br />We crashed inside printnum(). Let us inspect the arguments passed to printnum().<br />
  93. 93. What do we do now?<br />I thought I asked the questions!<br />We see where we crashed by examining frames from the stack. The "backtrace" command.<br />(gdb) backtrace<br />#0 0x080483b4 in printnum (x=0xff) at crash1.c:17<br />#1 0x080483a3 in main (argc=0x2, argv=0xbffff9b4) at crash1.c:12<br />We crashed inside printnum(). Let us inspect the arguments passed to printnum().<br />(gdb) info args<br />x = 0xff<br />
  94. 94. What do we do now?<br />I thought I asked the questions!<br />We see where we crashed by examining frames from the stack. The "backtrace" command.<br />(gdb) backtrace<br />#0 0x080483b4 in printnum (x=0xff) at crash1.c:17<br />#1 0x080483a3 in main (argc=0x2, argv=0xbffff9b4) at crash1.c:12<br />We crashed inside printnum(). Let us inspect the arguments passed to printnum().<br />(gdb) info args<br />x = 0xff<br />Isn't x a pointer to an integer (int *x)?<br />
  95. 95. That's right. x is an integer pointer, set to 0xff.<br />
  96. 96. That's right. x is an integer pointer, set to 0xff.<br />So it points to memory address 0x000000ff?<br />
  97. 97. That's right. x is an integer pointer, set to 0xff.<br />So it points to memory address 0x000000ff?<br />Yes. This memory cannot be referenced. Fetching its contents (*x) results in an error.<br />
  98. 98. That's right. x is an integer pointer, set to 0xff.<br />So it points to memory address 0x000000ff?<br />Yes. This memory cannot be referenced. Fetching its contents (*x) results in an error.<br />How did x get set to 0x000000ff?<br />
  99. 99. That's right. x is an integer pointer, set to 0xff.<br />So it points to memory address 0x000000ff?<br />Yes. This memory cannot be referenced. Fetching its contents (*x) results in an error.<br />How did x get set to 0x000000ff?<br />The answer lies in how printnum() was called.<br />
  100. 100. That's right. x is an integer pointer, set to 0xff.<br />So it points to memory address 0x000000ff?<br />Yes. This memory cannot be referenced. Fetching its contents (*x) results in an error.<br />How did x get set to 0x000000ff?<br />The answer lies in how printnum() was called.<br />Let us switch to its calling frame - frame 1 - and inspect frame 1's local variables.<br />
  101. 101. gdb's "frame <n>" command lets you switch context to other frames.<br />
  102. 102. gdb's "frame <n>" command lets you switch context to other frames.<br />(gdb) frame 1<br />#1 0x080483a3 in main (argc=0x2, argv=0xbffff9b4) at crash1.c:12<br />12 printnum(pointer);<br />
  103. 103. gdb's "frame <n>" command lets you switch context to other frames.<br />(gdb) frame 1<br />#1 0x080483a3 in main (argc=0x2, argv=0xbffff9b4) at crash1.c:12<br />12 printnum(pointer);<br />Inspect frame 1's local variables.<br />
  104. 104. gdb's "frame <n>" command lets you switch context to other frames.<br />(gdb) frame 1<br />#1 0x080483a3 in main (argc=0x2, argv=0xbffff9b4) at crash1.c:12<br />12 printnum(pointer);<br />Inspect frame 1's local variables.<br />(gdb) info locals<br />number = 0xff<br />pointer = 0xff<br />
  105. 105. gdb's "frame <n>" command lets you switch context to other frames.<br />(gdb) frame 1<br />#1 0x080483a3 in main (argc=0x2, argv=0xbffff9b4) at crash1.c:12<br />12 printnum(pointer);<br />Inspect frame 1's local variables.<br />(gdb) info locals<br />number = 0xff<br />pointer = 0xff<br />Do you see the second bug now?<br />
  106. 106. gdb's "frame <n>" command lets you switch context to other frames.<br />(gdb) frame 1<br />#1 0x080483a3 in main (argc=0x2, argv=0xbffff9b4) at crash1.c:12<br />12 printnum(pointer);<br />Inspect frame 1's local variables.<br />(gdb) info locals<br />number = 0xff<br />pointer = 0xff<br />Do you see the second bug now?<br />We are reading the number 255 (0xff) and assigning it to the pointer directly.<br />
  107. 107. Absolutely correct. What should we do instead?<br />
  108. 108. Absolutely correct. What should we do instead?<br />Make the pointer POINT to the number.<br />
  109. 109. Absolutely correct. What should we do instead?<br />Make the pointer POINT to the number.<br />Set the pointer's value to be the ADDRESS of the number and not its value.<br />
  110. 110. Bug #2 - Pointer mess-up<br />The faulting statement is:<br />pointer = number;<br />
  111. 111. Bug #2 - Pointer mess-up<br />The faulting statement is:<br />pointer = number;<br />Instead it should be:<br />pointer = &number; //address of number<br />
  112. 112. Bug #2 - Pointer mess-up<br />The faulting statement is:<br />pointer = number;<br />Instead it should be:<br />pointer = &number; //address of number<br />Let us see what happens at assembly level.<br />Dump instructions at EIP and inspect the registers.<br />
  113. 113. (gdb) frame 0<br />
  114. 114. (gdb) frame 0<br />(gdb) x/10i $eip<br />=> 0x80483b4 <printnum+12>: push DWORD PTR [eax]<br /> 0x80483b6 <printnum+14>: push 0x8048488<br /> 0x80483bb <printnum+19>: call 0x804828c <printf@plt><br /> 0x80483c0 <printnum+24>: add esp,0x10<br /> 0x80483c3 <printnum+27>: leave <br /> 0x80483c4 <printnum+28>: ret <br />
  115. 115. (gdb) frame 0<br />(gdb) x/10i $eip<br />=> 0x80483b4 <printnum+12>: push DWORD PTR [eax]<br /> 0x80483b6 <printnum+14>: push 0x8048488<br /> 0x80483bb <printnum+19>: call 0x804828c <printf@plt><br /> 0x80483c0 <printnum+24>: add esp,0x10<br /> 0x80483c3 <printnum+27>: leave <br /> 0x80483c4 <printnum+28>: ret <br />(gdb) info registers<br />eax 0xff 0xff<br />ecx 0x0 0x0<br />edx 0x0 0x0<br />ebx 0x40148f50 0x40148f50<br />esp 0xbffff938 0xbffff938<br />ebp 0xbffff948 0xbffff948<br />esi 0x40012780 0x40012780<br />edi 0xbffff9b4 0xbffff9b4<br />eip 0x80483b4 0x80483b4 <printnum+12><br />eflags 0x10292 [ AF SF IF RF ]<br />
  116. 116. (gdb) frame 0<br />(gdb) x/10i $eip<br />=> 0x80483b4 <printnum+12>: push DWORD PTR [eax]<br /> 0x80483b6 <printnum+14>: push 0x8048488<br /> 0x80483bb <printnum+19>: call 0x804828c <printf@plt><br /> 0x80483c0 <printnum+24>: add esp,0x10<br /> 0x80483c3 <printnum+27>: leave <br /> 0x80483c4 <printnum+28>: ret <br />(gdb) info registers<br />eax 0xff 0xff<br />ecx 0x0 0x0<br />edx 0x0 0x0<br />ebx 0x40148f50 0x40148f50<br />esp 0xbffff938 0xbffff938<br />ebp 0xbffff948 0xbffff948<br />esi 0x40012780 0x40012780<br />edi 0xbffff9b4 0xbffff9b4<br />eip 0x80483b4 0x80483b4 <printnum+12><br />eflags 0x10292 [ AF SF IF RF ]<br />We are trying to push a value whose address is stored in EAX. This address is 0x000000ff.<br />
  117. 117. There are two PUSHes. The first pushes the contents at address EAX onto the stack.<br />
  118. 118. There are two PUSHes. The first pushes the contents at address EAX onto the stack.<br />EAX stores the address of the pointer x.<br />
  119. 119. There are two PUSHes. The first pushes the contents at address EAX onto the stack.<br />EAX stores the address of the pointer x.<br />DWORD PTR [EAX] implies *x (contents at addr x)<br />
  120. 120. There are two PUSHes. The first pushes the contents at address EAX onto the stack.<br />EAX stores the address of the pointer x.<br />DWORD PTR [EAX] implies *x (contents at addr x)<br />What does the second PUSH do? push 0x08048488<br />
  121. 121. There are two PUSHes. The first pushes the contents at address EAX onto the stack.<br />EAX stores the address of the pointer x.<br />DWORD PTR [EAX] implies *x (contents at addr x)<br />What does the second PUSH do? push 0x08048488<br />0x08048488 looks like a memory address. Notice that the next instruction is a CALL to printf.<br />=> 0x80483b4 <printnum+12>: push DWORD PTR [eax]<br /> 0x80483b6 <printnum+14>: push 0x8048488<br /> 0x80483bb <printnum+19>: call 0x804828c <printf@plt><br />
  122. 122. There are two PUSHes. The first pushes the contents at address EAX onto the stack.<br />EAX stores the address of the pointer x.<br />DWORD PTR [EAX] implies *x (contents at addr x)<br />What does the second PUSH do? push 0x08048488<br />0x08048488 looks like a memory address. Notice that the next instruction is a CALL to printf.<br />=> 0x80483b4 <printnum+12>: push DWORD PTR [eax]<br /> 0x80483b6 <printnum+14>: push 0x8048488<br /> 0x80483bb <printnum+19>: call 0x804828c <printf@plt><br />The two PUSHes set up the parameters passed to printf().<br />
  123. 123. printf()<br />printf("The number supplied is %d", *x);<br />
  124. 124. printf()<br />printf("The number supplied is %d", *x);<br /> push DWORD PTR [eax]<br />
  125. 125. printf()<br />printf("The number supplied is %d", *x);<br /> push DWORD PTR [eax]<br /> push 0x8048488<br />
  126. 126. printf()<br />printf("The number supplied is %d", *x);<br /> push DWORD PTR [eax]<br /> push 0x8048488<br /> call 0x804828c<br />
  127. 127. printf()<br />printf("The number supplied is %d", *x);<br /> push DWORD PTR [eax]<br /> push 0x8048488<br /> call 0x804828c<br />Remember our discussion in the tutorial<br />"HOW FUNCTIONS WORK?"<br />
  128. 128. So where does address 0x08048488 point to?<br />
  129. 129. So where does address 0x08048488 point to?<br />It should point to the string:<br />"The number supplied is %d"<br />
  130. 130. So where does address 0x08048488 point to?<br />It should point to the string:<br />"The number supplied is %d"<br />Let us use the "x" command and find out. We shall use "x/s" to display the output as a string.<br />
  131. 131. So where does address 0x08048488 point to?<br />It should point to the string:<br />"The number supplied is %d"<br />Let us use the "x" command and find out. We shall use "x/s" to display the output as a string.<br />(gdb) x/s 0x08048488<br />0x8048488: "The number supplied is %d"<br />
  132. 132. Disassembling printnum()<br />To wrap this up, let us dive into the assembly code of function printnum().<br />We shall map out the concepts discussed in "HOW FUNCTIONS WORK".<br />
  133. 133. Use the "disassemble" command<br />
  134. 134. Use the "disassemble" command<br />(gdb) disassemble printnum<br />Dump of assembler code for function printnum:<br /> 0x080483a8 <+0>: push ebp<br /> 0x080483a9 <+1>: mov ebp,esp<br /> 0x080483ab <+3>: sub esp,0x8<br /> 0x080483ae <+6>: sub esp,0x8<br /> 0x080483b1 <+9>: mov eax,DWORD PTR [ebp+0x8]<br />=> 0x080483b4 <+12>: push DWORD PTR [eax]<br /> 0x080483b6 <+14>: push 0x8048488<br /> 0x080483bb <+19>: call 0x804828c <printf@plt><br /> 0x080483c0 <+24>: add esp,0x10<br /> 0x080483c3 <+27>: leave <br /> 0x080483c4 <+28>: ret <br />End of assembler dump.<br />
  135. 135. Use the "disassemble" command<br />(gdb) disassemble printnum<br />Dump of assembler code for function printnum:<br /> 0x080483a8 <+0>: push ebp<br /> 0x080483a9 <+1>: mov ebp,esp<br /> 0x080483ab <+3>: sub esp,0x8<br /> 0x080483ae <+6>: sub esp,0x8<br /> 0x080483b1 <+9>: mov eax,DWORD PTR [ebp+0x8]<br />=> 0x080483b4 <+12>: push DWORD PTR [eax]<br /> 0x080483b6 <+14>: push 0x8048488<br /> 0x080483bb <+19>: call 0x804828c <printf@plt><br /> 0x080483c0 <+24>: add esp,0x10<br /> 0x080483c3 <+27>: leave <br /> 0x080483c4 <+28>: ret <br />End of assembler dump.<br />Let us map this disassembly to the various components of a function.<br />
  136. 136. printnum() disassembly<br />Prologue<br /> push ebp<br /> mov ebp,esp<br /> sub esp,0x8<br /> sub esp,0x8<br /> mov eax,DWORD PTR [ebp+0x8]<br /> push DWORD PTR [eax]<br /> push 0x8048488<br /> call 0x804828c <printf@plt><br /> add esp,0x10<br /> leave <br /> ret <br />Body<br />Epilogue<br />Return<br />
  137. 137. printnum() disassembly<br />Prologue<br /> push ebp<br /> mov ebp,esp<br /> sub esp,0x8<br /> sub esp,0x8<br /> mov eax,DWORD PTR [ebp+0x8]<br />> push DWORD PTR [eax]<br /> push 0x8048488<br /> call 0x804828c <printf@plt><br /> add esp,0x10<br /> leave <br /> ret <br />Body<br />Epilogue<br />Return<br />Crash occurs at "push dword ptr [eax]".<br />
  138. 138. printnum() disassembly<br />Prologue<br /> push ebp<br /> mov ebp,esp<br /> sub esp,0x8<br /> sub esp,0x8<br /> mov eax,DWORD PTR [ebp+0x8]<br />> push DWORD PTR [eax]<br /> push 0x8048488<br /> call 0x804828c <printf@plt><br /> add esp,0x10<br /> leave <br /> ret <br />Body<br />Epilogue<br />Return<br />Crash occurs at "push dword ptr [eax]".<br />Let us see how the stack is built up.<br />
  139. 139. Before printnum() is called<br /> push ebp<br /> mov ebp,esp<br /> sub esp,0x8<br /> sub esp,0x8<br /> mov eax,DWORD PTR [ebp+0x8]<br /> push DWORD PTR [eax]<br /> push 0x8048488<br /> call 0x804828c <printf@plt><br /> add esp,0x10<br /> leave <br /> ret <br />Pointer x is pushed on the stack...<br />0x000000ff<br />ESP<br />...<br />EBP<br />
  140. 140. Before printnum() is called<br />> push ebp<br /> mov ebp,esp<br /> sub esp,0x8<br /> sub esp,0x8<br /> mov eax,DWORD PTR [ebp+0x8]<br /> push DWORD PTR [eax]<br /> push 0x8048488<br /> call 0x804828c <printf@plt><br /> add esp,0x10<br /> leave <br /> ret <br />...and printnum is CALLed.<br />Saved EIP<br />ESP<br />0x000000ff<br />param 1<br />...<br />EBP<br />
  141. 141. Prologue<br />push ebp<br />> mov ebp,esp<br /> sub esp,0x8<br /> sub esp,0x8<br /> mov eax,DWORD PTR [ebp+0x8]<br /> push DWORD PTR [eax]<br /> push 0x8048488<br /> call 0x804828c <printf@plt><br /> add esp,0x10<br /> leave <br /> ret <br />Old EBP<br />ESP<br />Save the old frame pointer.<br />Saved EIP<br />0x000000ff<br />param 1<br />...<br />EBP<br />
  142. 142. Prologue<br />push ebp<br />mov ebp,esp<br />> sub esp,0x8<br /> sub esp,0x8<br /> mov eax,DWORD PTR [ebp+0x8]<br /> push DWORD PTR [eax]<br /> push 0x8048488<br /> call 0x804828c <printf@plt><br /> add esp,0x10<br /> leave <br /> ret <br />Old EBP<br />EBP<br />ESP<br />Set the EBP to the current frame.<br />Saved EIP<br />0x000000ff<br />param 1<br />...<br />
  143. 143. Prologue<br />push ebp<br />mov ebp,esp<br /> sub esp,0x8<br /> sub esp,0x8<br />> mov eax,DWORD PTR [ebp+0x8]<br /> push DWORD PTR [eax]<br /> push 0x8048488<br /> call 0x804828c <printf@plt><br /> add esp,0x10<br /> leave <br /> ret <br />...<br />ESP<br />...<br />...<br />...<br />Old EBP<br />EBP<br />Leave some space on the stack (16 bytes)<br />Saved EIP<br />0x000000ff<br />param 1<br />...<br />
  144. 144. Body<br />push ebp<br />mov ebp,esp<br /> sub esp,0x8<br /> sub esp,0x8<br />mov eax,DWORD PTR [ebp+0x8]<br />> push DWORD PTR [eax]<br /> push 0x8048488<br /> call 0x804828c <printf@plt><br /> add esp,0x10<br /> leave <br /> ret <br />...<br />ESP<br />...<br />...<br />...<br />Old EBP<br />EBP<br />EAX = 0x000000ff<br />Saved EIP<br />0x000000ff<br />param 1<br />...<br />
  145. 145. Segmentation Fault!<br />push ebp<br />mov ebp,esp<br /> sub esp,0x8<br /> sub esp,0x8<br />mov eax,DWORD PTR [ebp+0x8]<br />>push DWORD PTR [eax]<br /> push 0x8048488<br /> call 0x804828c <printf@plt><br /> add esp,0x10<br /> leave <br /> ret <br />...<br />ESP<br />...<br />...<br />...<br />Old EBP<br />EBP<br />Memory at 0x000000ff cannot be referenced.<br />Saved EIP<br />0x000000ff<br />param 1<br />...<br />
  146. 146. Segmentation Fault!<br />push ebp<br />mov ebp,esp<br /> sub esp,0x8<br /> sub esp,0x8<br />mov eax,DWORD PTR [ebp+0x8]<br />>push DWORD PTR [eax]<br /> push 0x8048488<br /> call 0x804828c <printf@plt><br /> add esp,0x10<br /> leave <br /> ret <br />...<br />ESP<br />...<br />...<br />...<br />Old EBP<br />EBP<br />Memory at 0x000000ff cannot be referenced.<br />Saved EIP<br />0x000000ff<br />param 1<br />What will stack memory contain at this moment?<br />...<br />
  147. 147. Examine stack memory and registers<br />
  148. 148. Examine stack memory and registers<br />(gdb) x/16xw $esp<br />0xbffff938: 0x0000000a 0x00000000 0x40042550 0x40012df8<br />0xbffff948: 0xbffff968 0x080483a3 0x000000ff 0xbffff9b4<br />0xbffff958: 0xbffff968 0x080483dc 0x000000ff 0x000000ff<br />0xbffff968: 0xbffff988 0x4002e7f7 0x00000002 0xbffff9b4<br />
  149. 149. Examine stack memory and registers<br />(gdb) x/16xw $esp<br />0xbffff938: 0x0000000a 0x00000000 0x40042550 0x40012df8<br />0xbffff948: 0xbffff968 0x080483a3 0x000000ff 0xbffff9b4<br />0xbffff958: 0xbffff968 0x080483dc 0x000000ff 0x000000ff<br />0xbffff968: 0xbffff988 0x4002e7f7 0x00000002 0xbffff9b4<br />(gdb) info registers<br />eax 0xff<br />ecx 0x0<br />edx 0x0<br />ebx 0x40148f50<br />esp 0xbffff938<br />ebp 0xbffff948<br />esi 0x40012780<br />edi 0xbffff9b4<br />eip 0x80483b4<br />
  150. 150. Examine stack memory and registers<br />(gdb) x/16xw $esp<br />0xbffff938: 0x0000000a 0x00000000 0x40042550 0x40012df8<br />0xbffff948: 0xbffff968 0x080483a3 0x000000ff 0xbffff9b4<br />0xbffff958: 0xbffff968 0x080483dc 0x000000ff 0x000000ff<br />0xbffff968: 0xbffff988 0x4002e7f7 0x00000002 0xbffff9b4<br />(gdb) info registers<br />eax 0xff<br />ecx 0x0<br />edx 0x0<br />ebx 0x40148f50<br />esp 0xbffff938<br />ebp 0xbffff948<br />esi 0x40012780<br />edi 0xbffff9b4<br />eip 0x80483b4<br />0x0000000a<br />ESP0xbffff938:<br />0x00000000<br />0xbffff93c:<br />0x40042550<br />0xbffff940:<br />0xbffff944:<br />0x40012df8<br />EBP0xbffff948:<br />0xbffff968<br /> Saved EIP 0xbffff94c:<br />0x080483a3<br /> Param 1 0xbffff950:<br />0x000000ff<br />0xbffff954:<br />0xbffff9b4<br />0xbffff958:<br />0xbffff968<br />
  151. 151. Recap<br />We have seen how to analyze crashes and identify causes of errors.<br />We also saw a lot of gdb commands and when to use them.<br />
  152. 152. Summary of gdb commands<br />
  153. 153. A few gdb commands<br />
  154. 154. A few more gdb commands<br />
  155. 155. Review<br />
  156. 156. END<br />photo: Brian Searle - bit.ly/fpcxY9<br />
  • buster20

    Nov. 24, 2020
  • getasutosh

    May. 20, 2020
  • pradnyakulkarni6

    Feb. 18, 2020
  • ShakeelAhmad147

    Dec. 17, 2019
  • joostepoost

    May. 14, 2019
  • HaithamAdel4

    Mar. 5, 2019
  • redhat

    Feb. 17, 2019
  • anandngiri

    Dec. 5, 2018
  • XingXingXingXing

    Feb. 10, 2018
  • ssuser12fe9c

    Sep. 26, 2017
  • shadyproject

    Jul. 29, 2017
  • Neeraj2708

    Jan. 20, 2017
  • MackenzieJiayuLu

    Oct. 22, 2016
  • IgorBezukh

    Feb. 19, 2016
  • abrahamsinai

    Jan. 15, 2016
  • shaochangbin

    Jan. 13, 2016
  • VanZekovich

    Nov. 6, 2015
  • weck

    Oct. 23, 2015
  • oldchic

    Jun. 26, 2015
  • WeiweiJiang3

    Jun. 23, 2015

A quick tutorial on what debuggers are and how to use them. We present a debugging example using GDB. At the end of this tutorial, you will be able to work your way through a crash and analyze the cause of the error responsible for the crash.

Views

Total views

31,271

On Slideshare

0

From embeds

0

Number of embeds

11,736

Actions

Downloads

0

Shares

0

Comments

0

Likes

45

×