-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathREADME-GDB
More file actions
executable file
·204 lines (152 loc) · 6.46 KB
/
Copy pathREADME-GDB
File metadata and controls
executable file
·204 lines (152 loc) · 6.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
GDB is a powerful debugger for the C/C++ languages.
There are plenty of tutorials on the Web, so this will
be about the commands I personally use all the times.
Many other ways of using gdb exists.
Tip: remember that for easy debugging, your program must
have been compiled with debug symbols (at least -g with GNU gcc).
also, remember that optimized code might be difficult to debug
as the compiler moved your code around when optimizing.
Tip: to know more about any command, simply ask for it:
(gdb) help layout
Change the layout of windows.
Usage: layout prev | next | <layout_name>
Layout names are:
src : Displays source and command windows.
asm : Displays disassembly and command windows.
split : Displays source, disassembly and command windows.
regs : Displays register window. If existing layout
is source/command or assembly/command, the
register window is displayed. If the
source/assembly/command (split) is displayed,
the register window is displayed with
the window that has current logical focus.
=======================================================================
Launching and stopping
=======================================================================
To launch GDB, there are several ways.
The most obvious way is to have gdb start your program.
$> gdb your-program
(gdb) run <with you arguments here>
Ctrl-C stops the execution.
To know where you are:
(gdb) where
#0 diskboot (_eax=1785688930, _ebx=129984) at loader.c:122
#1 0x00007c7d in protcseg () at boot.S:151
gives you the current call stack, on the current thread.
To know which thread you are on:
(gdb) thread
[Current thread is 1 (Thread 1)]
(gdb) info threads
Id Target Id Frame
* 1 Thread 1 (CPU#0 [running]) diskboot (_eax=1785688930, _ebx=129984) at loader.c:122
You can kill your program at any time and then restart it.
You can even "make" it without leaving gdb.
(gdb) kill
Kill the program being debugged? (y or n) y
(gdb) make
(gdb) run
Tip: if you kill your program, edit it, re-make it outside of gdb,
gdb is smart enough to know and reload your program before running it.
But even better, you can set breakpoints:
(gdb) br *0x7c00
(gdb) br boot.S:136
(gdb) br diskboot
(gdb) br loader.c:122
To know what breakpoints you already have:
(gdb) info br
Num Type Disp Enb Address What
1 breakpoint keep y 0x00007c00 boot.S:53
breakpoint already hit 1 time
2 breakpoint keep y 0x00007c56 boot.S:136
breakpoint already hit 1 time
3 breakpoint keep y 0x00007db5 in diskboot at loader.c:122
breakpoint already hit 1 time
You can also use watches... which is just incredibly powerful.
(gdb) help watch
Set a watchpoint for an expression.
Usage: watch [-l|-location] EXPRESSION
A watchpoint stops execution of your program whenever the value of
an expression changes.
If -l or -location is given, this evaluates EXPRESSION and watches
the memory to which it refers.
(gdb)
For example, you can use it to stop whenever a memory location is changed.
Assuming you have a variable i, let's say a global variable.
(gdb) p /x &i
$1 = 0x1001a0
(gdb) watch -l *0x1001a0
Hardware watchpoint 6: -location *0x1001a0
(gdb)
=======================================================================
Execution
=======================================================================
Now commands related to executing your program, when you are stopped
at a breakpoint or following a Crtl-C.
(gdb) cont
(gdb) step
(gdb) next
(gdb) finish
Tip: you can use them as single character commands: c,s,n,f
Tip: note that once you have typed a command, hitting return will repeat it.
As you can see, gdb works line by line, using regular commands.
Sometimes, it is hard to see where you are at in your code.
To see more of the sources, you can use several approaches.
First, you can use the list command:
(gdb) list
or
(gdb) l 120,133
If you want to avoid all this listing commands, you can ask gdb to change
its layout of the window, showing you different panes.
You can cycle through the different layout with the layout command:
(gdb) layout next
The source layout is probably the most natural starting point.
(gdb) layout src
Tip: resize your terminal window before starting gdb and
certainly before issuing the layout src.
=======================================================================
Printing / Displaying
=======================================================================
To print a variable:
(gdb) print your_variable
(gdb) p /x your_variable
You can display also, in which case, gdb will print the variable
whenever it stops.
(gdb) display /x your_variable
=======================================================================
Attaching to a running process
=======================================================================
You can also attach to a currently running program.
See the attach command.
=======================================================================
Remote debugging
=======================================================================
This is especially useful in the embedded world, either when debugging
with JTAG hardware debuggers or with Qemu.
Qemu embeds a GDB stub so that gdb can attach to qemu... right up to
the very instruction executed by your program. Just fantastic.
$> qemu-system-i386 <you options> -s -S
In another terminal window:
$> gdb boot.elf
(gdb) br *0x7c00
(gdb) target remote:1234
0x0000fff0 in ?? ()
(gdb) cont
Continuing.
Breakpoint 1, start () at boot.S:53
53 cli # Disable interrupts
(gdb)
=======================================================================
Loading symbols
=======================================================================
To work, gdb needs to know the symbols of your program.
Gdb reads the symbols from your program file, not from the executing process.
$> gdb toto
Reading symbols from toto...done.
Sometimes, it is necessary to load symbols.
It is the case in our step1, to switch from the boot.elf symbols
to the kernel.elf symbols when the loader is done loading the kernel.elf
and jumping to the entry point in the kernel.
(gdb) symbol kernel.elf
Load new symbol table from "kernel.elf"? (y or n) y
Reading symbols from kernel.elf...done.
(gdb)