Skip to content

Commit cfc0007

Browse files
committed
Chapter 8 edits
1 parent e433aef commit cfc0007

File tree

3 files changed

+192
-33
lines changed

3 files changed

+192
-33
lines changed

00-FrontMatter.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ header-includes:
2525
- \renewcommand{\backspace}{Backspace \backspacesymbol}
2626
- \let\tabsymbol\tab
2727
- \renewcommand{\tab}{Tab \tabsymbol}
28+
- \usepackage{afterpage}
2829

2930
include-before: |
3031
\pagestyle{empty}

08-Debugging-with-GDB.md

Lines changed: 191 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
## Motivation
44

55
You thought you were getting a bargain when you bought that pocket watch from that scary old lady at the flea market in the French Quarter.
6-
Little did you realize that pocket watch did more than just tell time[^tell-time].
6+
Little did you realize that pocket watch did more than just tell time.[^tell-time]
77
In fact, holding the button on the side *slows down* time.
88

99
At first it's a novelty.
1010
You prank your roommate.
1111
Maybe take some extra time on a test.
1212
Steal a quick bagel for breakfast.
13-
Rob a bank[^escalation]...
13+
Rob a bank...[^escalation]
1414

1515
It was all fun up to this point.
1616
But now you're here: standing in front of at an array of red-hot lasers, trapped in the vault of the Big Bank of New York, wondering where it all went wrong, and wearing a fancy turtle neck.
@@ -39,14 +39,14 @@ You cut the wrong blue wire!
3939

4040
You reach into your pocket to grab your watch and reset time.
4141
Instead, you pull out that pastrami sandwich from last lab.
42-
Also you've turned into a raccoon somehow.
42+
Also, you've turned into a raccoon somehow.
4343

44-
You wake up[^dream].
44+
You wake up.[^dream]
4545

46-
In real life, you may not be able to slow down or reset time analyze disasters in detail[^bank-robber].
46+
In real life, you may not be able to slow down or reset time to analyze disasters in detail.[^bank-robber]
4747
You can, however, slow down disasters as they happen in your programs.
4848

49-
Using a **debugger** you can slow down the execution of your programs to help you figure out why it's not working.
49+
Using a **debugger**, you can slow down the execution of your programs to help you figure out why it's not working.
5050
A debugger can't automatically tell you what's broken, but it can...
5151

5252
- step through your code line by line
@@ -59,36 +59,153 @@ In your bank robber dream, the watch allowed you to slow down time to see what s
5959
In real life, a debugger allows you to slow down the execution of your program, so that you can see where and when it breaks.
6060
It's still up to you to figure out why it's breaking and how to fix your bugs, but a debugger can definitely give you some clues to make it easier to find them.
6161

62-
In this lab, we'll be using the GNU Debugger (`gdb`) to debug a couple of C++ programs.
62+
We'll be using the GNU Debugger (`gdb`) to debug a couple of C++ programs.
6363
`gdb`, like `g++`, is open source software.
64-
There are GUI frontends available for `gdb`, but in this class, we'll be using the command line interface.
64+
There are GUI frontends available for `gdb`, but in this chapter, we'll be using the command line interface.
6565

6666
### Takeaways
6767

68-
- Learn to debug C++ projects with `gdb`
69-
- Step through the execution of a compiled C++ program
70-
- Inspect the contents of program variables
68+
- Learn general debugging practices
69+
- Step through the execution of a compiled C++ program
70+
- Inspect the contents of program variables
7171

7272
## Walkthrough
7373

74+
### Fatherly Debugging Advice
75+
76+
It's a sunny afternoon, so I take off work early and come by to pick you up from school.
77+
You run up and hop in the front seat of the car.
78+
"Hey kiddo, how was school? Do you want to get some ice cream?"
79+
80+
We drive over to the ice cream shoppe and I pull the ol' steering-with-my-knees trick
81+
that always makes you scream. "Dad! Stop it, you'll hit someone!"
82+
I laugh and mock-begrudingly put my hands back on the wheel.
83+
84+
We sit down in a booth to enjoy a couple of sundaes.
85+
"How was your day? Are the other kids treating you well?" I ask.
86+
87+
"School was fine. I did great on my English paper! But..."
88+
You furrow your brow.
89+
90+
"What's on your mind?"
91+
92+
"Well, some of my friends have been programming.
93+
And sometimes their programs don't work, and they have to fix them.
94+
And I guess I'm worried that when my program doesn't work I won't be able to fix it!"
95+
96+
"My child," I begin.
97+
98+
I put a hand on your shoulder the way only a father can.
99+
100+
"My dearest,"
101+
102+
I put another hand on your shoulder.
103+
104+
"It seems like only yesterday you were but a wee babe.
105+
How you did cry and scream and do other things that babies do!
106+
I lost more sleep over you than I did working 26 hour shifts at the smoke alarm testing factory."
107+
108+
I put another hand on your shoulder.
109+
110+
"But there was one thing that always calmed you down.
111+
The instant I'd sit you next to a computer you'd smile and coo!
112+
Many an evening I rocked you to sleep cradled between the screen and keyboard of a Thinkpad 701C.
113+
That's when I knew you'd grow up to be a great programmer."
114+
115+
I put another hand on your shoulder. You are visibly embarrassed at this point.
116+
117+
"And now look at you! Practically all grown up!
118+
Your mother and I are so proud of you.
119+
Everyone has trouble with programs from time to time."
120+
121+
I put another hand on your shoulder.
122+
123+
"Here's what I do when I have to fix a program:"
124+
125+
#### 1. What happened? What should have happened?
126+
127+
You should have an idea of how your program ought to work in your mind while programming.
128+
Maybe you've got a homework assignment writeup to go off of, or a design document that you wrote,
129+
or just an idea in your head that you're implementing.
130+
131+
Regardless of where that idea comes from, take a second to identify the wrong behaviour you're seeing
132+
and to figure out what your program should have done instead.
133+
If you can, get a real piece of paper and actually draw out a picture of what your program is doing;
134+
for example, if you're making a binary tree, draw the tree, or if you're communicating to a server,
135+
draw/write out the protocol your server and client should be following.
136+
137+
#### 2. What the heck did you do to break it?!
138+
139+
Was your program working earlier?
140+
If so, think through the changes you just made.
141+
(You may find consulting `git diff` to be helpful!)
142+
How might they have caused the bug?
143+
144+
(If your program didnt work right in the first place, you'll have to try some other debugging technique. Sorry.)
145+
146+
#### 3. How is the program getting the wrong result?
147+
148+
Start from where you saw the bug and work your way back through your program.
149+
What execution path did it follow? What values do your variables have?
150+
How do those values get set?
151+
152+
Make generous use of print (`cout`) statements! Print out the contents of your variables and
153+
print out messages that tell you what code is executing.
154+
Don't take anything for granted!
155+
Use those print statements to check your assumptions about how your code works.
156+
157+
#### 4. Talk it out.
158+
159+
\afterpage{% Put bertha on her own page
160+
\begin{figure}[p!]
161+
\centering
162+
\includegraphics[width=\textwidth]{08/bertha.png}
163+
\caption{Bertha!}
164+
\end{figure}
165+
\clearpage
166+
}
167+
168+
On the next page you will find Bertha.[^picture]
169+
She's very curious about people and would love to hear about your program.
170+
So, prop that page up next to your computer and explain exactly what is wrong with your program,
171+
just like you would explain it to a friend.
172+
Why do you think it's broken?
173+
What fixes did you try?
174+
175+
(This may seem foolish, but this techinque once revealed to me that I had been debugging code
176+
for an hour under the misapprehension that 9 was a prime number.
177+
You'd be amazed at the things you don't realize until you think about how to explain something
178+
to someone else.)
179+
180+
#### 5. When all else fails, try again later.
181+
182+
If you've got a bug that you just can't seem to figure out, take a break.
183+
If there are other obvious bugs, fixing those may reveal the root cause of your problem bug.
184+
Otherwise, take a walk, or even better, get a good night's sleep and come back to it in the morning.
185+
186+
These debugging tips work for any program (and plenty of not-computer-related problems to boot).
187+
However, a debugger tool can make life easier for you, especially when you are tracing the execution
188+
of your program and inspecting how it behaves.
189+
74190
### Compilin' for Debuggin'
75191

76-
When you compile a program, you lose a lot of information.
192+
Compiled programs don't contain all the information that their source code does.
77193
All of the C++ code that you write gets translated into machine-executable code.
78194
As far as your CPU is concerned, there's really no need for function names, curly braces, or comments.
195+
So, if you try to debug a program that's compiled in the usual manner, you'll have to wade through a lot of
196+
hex numbers and assembly code.
79197

80-
As a human person, you will need those things.
81-
82-
If we plan to debug our code with `gdb`, we need to ask `g++` to to keep the details of our source code when we compile it.
198+
As a human person, you'd rather be able to look at your actual source code in the debugger.
199+
Fortunately, there is a way to ask `g++` to to keep the details of our source code when we compile it.
83200
Whenever you compile your code, simply add the `-g` flag to your `g++ command`.
84201
For example:
85202

86-
~~~shell
203+
~~~
87204
$ g++ -g main.cpp
88205
~~~
89206

90207
If you forget the `-g`, `gdb` will have a lot less information to work with.
91-
As a result, debugging will be much less useful.
208+
As a result, debugging will be much less fun.
92209

93210
### Starting GNU Debugger
94211

@@ -156,18 +273,18 @@ In order to debug your program, it has to be running.
156273
The `run` command is likely one of the first commands you will run whenever you debug a program.
157274

158275
If you need to pass any command line arguments to the program, you'll pass them to the run command.
159-
For example, if we wanted to debug `g++`[^dont]...
276+
For example, if we wanted to debug `g++`...[^dont]
160277

161278
~~~
162279
$ gdb g++
163280
(gdb) run funcs.cpp main.cpp
164281
~~~
165282

166-
... would be similar to running `g++ funcs.cpp main.cpp` outside of `gdb`.
283+
...would be similar to running `g++ funcs.cpp main.cpp` outside of `gdb`.
167284

168285
#### Stopping at the right time
169286

170-
If you don't want your program to pause at a specific line, you can place a **breakpoint**.
287+
If you want your program to pause at a specific line, you can place a **breakpoint**.
171288

172289
Assuming your program is not currently running, let's place a breakpoint at line 8 of `main.cpp`.
173290
Then, we'll run our program.
@@ -194,13 +311,13 @@ For example:
194311

195312
~~~
196313
(gdb) info breakpoints
197-
1 breakpoint keep y 0x000000000040086c in main() at main.cpp:8
198-
2 breakpoint keep y 0x000000000040088e in main() at main.cpp:10
199-
3 breakpoint keep y 0x0000000000400894 in main() at main.cpp:12
314+
1 breakpoint keep y 0x40086c in main() at main.cpp:8
315+
2 breakpoint keep y 0x40088e in main() at main.cpp:10
316+
3 breakpoint keep y 0x400894 in main() at main.cpp:12
200317
(gdb) delete 2
201318
(gdb) info breakpoints
202-
1 breakpoint keep y 0x000000000040086c in main() at main.cpp:8
203-
3 breakpoint keep y 0x0000000000400894 in main() at main.cpp:12
319+
1 breakpoint keep y 0x40086c in main() at main.cpp:8
320+
3 breakpoint keep y 0x400894 in main() at main.cpp:12
204321
(gdb) delete
205322
Delete all breakpoints? (y or n) y
206323
(gdb) info breakpoints
@@ -216,12 +333,20 @@ You can use the `backtrace` command to ask `gdb` where we currently are.
216333
#0 main () at main.cpp:8
217334
~~~
218335

219-
In the output, `gdb` will show you the current backtrace.
220-
Depending how many functions you've called, you'll see deeper and deeper traces.
336+
The backtrace shows you the function stack: starting from `main()`,
337+
which functions were called to get to the line that's currently executing?
338+
Think of it like a family history: this line of code lives in this function,
339+
which was called by this other function, which was called by *another* function,
340+
and so on and so forth all the way back to Adam, err, `main()`.
221341
In this case, we've only called `main()`, so that's the only line we see.
222-
You can also see the file name and line number.
342+
You can also see the file name and line number where the function is defined,
343+
along with the values of any arguments passed to it.
344+
345+
`backtrace` is usually the first tool you should reach for when debugging a segfault.
346+
It'll tell you right where your program is, and it might even show you the null pointer
347+
(if you're passing it as an argument to the function).
223348

224-
You can also use `list` to ask `gdb` to show you some source code to give you context.
349+
You can use `list` to ask `gdb` to show you some source code to give you context.
225350
Sometimes a line number isn't enough if you're too lazy to tab over to your text editor.
226351

227352
~~~
@@ -307,8 +432,37 @@ $2 = 7
307432
That makes a lot more sense!
308433

309434
You can use `print` to print out any variable that's in scope.
310-
You can also use `info locals` to check on the value of local variables.
311-
Try running it and make a note of the output.
435+
It even knows how to print out struct and class instances!
436+
437+
`print` will also happily print out the results of C++ expressions.
438+
You can dereference pointers, do arithmetic, and even call functions!
439+
440+
For a summary of all the variables in the current function, use `info locals`.
441+
`info` can show a bunch of other interesting data about your program and about `gdb`.
442+
443+
#### Setting the contents of variables
444+
445+
Sometimes you'll want to test out a theory --- maybe you think you've found your bug, and you want to
446+
make a quick change to see if you know how to fix it.
447+
You can't change the code while `gdb` is running it, but you can poke stuff in memory to your heart's content.
448+
449+
You can change the values of variables on the fly with the `set` command:
450+
451+
~~~
452+
(gdb) print x
453+
$1 = 7
454+
(gdb) set x = 30
455+
(gdb) print x
456+
$2 = 30
457+
(gdb) step
458+
11 if (x >= 10)
459+
~~~
460+
461+
Here, instead of continuing execution on line 9, the code jumps to line 11 since we changed the value of `x`!
462+
463+
There's a lot more that `gdb` can do --- disassembling functions, poking around in memory, debugging code running on other machines ---
464+
but the stuff in this chapter will cover all of your usual debugging needs.
465+
Happy debugging!
312466

313467
\newpage
314468
## Questions
@@ -335,7 +489,7 @@ Name: `______________________________`
335489
- `run arg1 arg2` runs the command with command line arguments `arg1` and `arg2`
336490
- `backtrace` or `bt` shows the call stack
337491

338-
### Setting breakpoints with `gdb`
492+
### Setting breakpoints
339493

340494
- `break main.cpp:10` will stop execution whenever line `10` in `main.cpp` is reached.
341495
- `continue` resumes running as normal.
@@ -344,7 +498,7 @@ Name: `______________________________`
344498
- `finish` runs until the current function returns.
345499
- `delete` removes all breakpoints.
346500

347-
### Looking at variables with `gdb`
501+
### Looking at variables
348502

349503
- `print VARIABLE` prints the contents of variable with name `VARIABLE`
350504
- `p VARIABLE` also works
@@ -364,7 +518,10 @@ Name: `______________________________`
364518

365519
## Further Reading
366520

521+
- [GDB manual](https://sourceware.org/gdb/current/onlinedocs/gdb/index.html)
367522
- [More on breakpoints](https://sourceware.org/gdb/current/onlinedocs/gdb/Breakpoints.html)
523+
- [KDbg, a GUI for gdb](http://www.kdbg.org/manual/)
524+
- [rr, tool that can record and replay program execution!](http://rr-project.org/)
368525

369526

370527
[^tell-time]: Actually it doesn't tell time at all.
@@ -376,3 +533,4 @@ Name: `______________________________`
376533
[^bank-robber]: In real life, hopefully you're not a bank robber either.
377534
[^dont]: Don't actually do this, though.
378535
We're just demonstrating how you'd pass command line arguments.
536+
[^picture]: Well, a picture of her. The publisher wouldn't let us include a live chicken tucked between the pages of the book.

08/bertha.png

3.03 MB
Loading

0 commit comments

Comments
 (0)