-
Notifications
You must be signed in to change notification settings - Fork 14
/
gdbhelpers
396 lines (349 loc) · 7.53 KB
/
gdbhelpers
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
define startupbreakpoints
set remotetimeout 86400
#set can-use-hw-watchpoints 0
#watch -l *(void**)0xfffffd00504bb000
#file
#add-symbol-file kernel-generic 0xffffff00000001a0
# For kernel
set architecture i386:x86-64
# For MBR, boot1, and portions of bootfat, bootiso, bootpxe
#set architecture i8086
# For majority of bootfat, bootpxe
#set architecture i386
set osabi none
#set scheduler-locking off
set scheduler-locking step
set range-stepping off
set may-call-functions off
#on is good for TCG, horrible for KVM or baremetal
set breakpoint always-inserted on
#exec-file kernel-generic
#symbol-file kernel-generic -o -0x000000ff80000000
hbreak cpu_debug_break
thbreak entry
commands
# cd ../lto
# cd ../small
# allow everything
# maintenance packet qqemu.sstep=1
# allow irqs only
# maintenance packet qqemu.sstep=5
# b isr_entry_13
# b unhandled_exception_handler
# b apic_spurious_handler
# #GP
# b isr_entry_8
# #UD
# b isr_entry_6
# b vpanic
# b validate_failed
hbreak modload_load_symbols
commands
printf "Loading %s with offset 0x%lx",$rdi,$rdx
eval "add-symbol-file %s -o 0x%lx",$rdi,$rdx
end
end
set may-call-functions off
end
define qemu
target remote localhost:1234
end
define walkstack
set $addr = $arg0
set $depth = $arg1
while $depth--
set $retaddr=*(long*)($addr+8)
set $nextframe=*(long*)$addr
if $retaddr < 0xffffffff80000000
echo Invalid address, stopping backtrace
loop_break
end
x /1i $retaddr
set $addr=$nextframe
end
end
define walkstacksafe
set $initframe = $arg0
python
try:
gdb.execute("walkstack $initframe 8")
except:
pass
end
end
define walkthreads
if $argc == 1
set $depth = $arg0
else
set $depth = 7
end
set $savecpu = $_thread
set $threadcount = thread_count
set $tid = 0
while $tid < $threadcount
echo ---------------------------------------------
set $ctx = threads[$tid].ctx
if $ctx != 0
printf "Thread %d trace:\n", $tid
x /1i $ctx->gpr.iret.rip
set $initframe = $ctx->gpr.r.n.rbp
if $initframe != 0
walkstacksafe $initframe
set $tid = $tid + 1
loop_continue
else
echo rbp is null
end
end
set $icpu = 0
while $icpu < cpu_count
if cpus[$icpu].cur_thread == &threads[$tid]
printf "Found thread %d on CPU %d\n", $tid, $icpu
eval "thread %d", ($icpu + 1)
walkstacksafe $rbp
loop_break
end
set $icpu = $icpu + 1
end
if $icpu == cpu_count
echo Could not find thread
end
set $tid = $tid + 1
end
eval "thread %d", $savecpu
end
define findtid
set $tid = $arg0
set $cpu_nr = 0
set $cpu_count = cpu_count
set $needle = threads + $tid
while $cpu_nr < $cpu_count
set $cpu_thr = cpus[$cpu_nr].cur_thread
if $cpu_thr == $needle
eval "thread %d", ($cpu_nr + 1)
eval "print cpus[%d]", ($cpu_nr)
loop_break
end
set $cpu_nr = $cpu_nr + 1
end
if $cpu_nr >= $cpu_count
print "Not running, here's thread context"
print threads[$tid]
end
end
define printtids
set $cpu_nr = 0
set $cpu_count = cpu_count
while $cpu_nr < $cpu_count
print cpus[$cpu_nr++].cur_thread - threads
end
end
define dumpn
dump binary memory $arg0 $arg1 $arg1+$arg2
end
define walkunwind_ctx
set $ctx = $arg0
# Save context
set $save_cr3 = $cr3
set $save_rip = $rip
set $save_rsp = $rsp
set $save_eflags = $eflags
set $save_ss = $ss
set $save_ds = $ds
set $save_es = $es
set $save_fs = $fs
set $save_gs = $gs
set $save_rax = $rax
set $save_rbx = $rbx
set $save_rcx = $rcx
set $save_rdx = $rdx
set $save_rsi = $rsi
set $save_rdi = $rdi
set $save_rbp = $rbp
set $save_r8 = $r8
set $save_r9 = $r9
set $save_r10 = $r10
set $save_r11 = $r11
set $save_r12 = $r12
set $save_r13 = $r13
set $save_r14 = $r14
set $save_r15 = $r15
# Set context
set $cr3 = $ctx.cr3
set $rip = $ctx.iret.rip
set $rsp = $ctx.iret.rsp
set $eflags = (uint32_t)$ctx.iret.rflags
set $ss = $ctx.iret.ss
set $ds = $ctx.s.n.ds
set $es = $ctx.s.n.es
set $fs = $ctx.s.n.fs
set $gs = $ctx.s.n.gs
set $rax = $ctx.r.n.rax
set $rbx = $ctx.r.n.rbx
set $rcx = $ctx.r.n.rcx
set $rdx = $ctx.r.n.rdx
set $rsi = $ctx.r.n.rsi
set $rdi = $ctx.r.n.rdi
set $rbp = $ctx.r.n.rbp
set $r8 = $ctx.r.n.r8
set $r9 = $ctx.r.n.r9
set $r10 = $ctx.r.n.r10
set $r11 = $ctx.r.n.r11
set $r12 = $ctx.r.n.r12
set $r13 = $ctx.r.n.r13
set $r14 = $ctx.r.n.r14
set $r15 = $ctx.r.n.r15
# Unwind
python
try:
gdb.execute("bt")
except:
pass
end
# Restore context
set $cr3 = $save_cr3
set $rip = $save_rip
set $rsp = $save_rsp
set $eflags = $save_eflags
set $ss = $save_ss
set $ds = $save_ds
set $es = $save_es
set $fs = $save_fs
set $gs = $save_gs
set $rax = $save_rax
set $rbx = $save_rbx
set $rcx = $save_rcx
set $rdx = $save_rdx
set $rsi = $save_rsi
set $rdi = $save_rdi
set $rbp = $save_rbp
set $r8 = $save_r8
set $r9 = $save_r9
set $r10 = $save_r10
set $r11 = $save_r11
set $r12 = $save_r12
set $r13 = $save_r13
set $r14 = $save_r14
set $r15 = $save_r15
end
define walkunwind
set $tid_loop = 0
printf "Unwinding %d threads\n", thread_count
while $tid_loop < thread_count
set $tid = $tid_loop++
set $ctx = threads[$tid].ctx
if $ctx
printf "\n"
printf "Unwinding thread %d (%s) runcpu=%d state=0x%x -----------------------------------------------\n", \
$tid, threads[$tid].name, run_cpu[$tid], threads[$tid].state
python
try:
gdb.execute("walkunwind_ctx $ctx.gpr")
except:
pass
end
end
end
end
define initsyms
add-symbol-file init
end
define modulesyms
set $midx = 0
set $mcount = loaded_modules.__sz
while $midx < $mcount
set $module_ptr = loaded_modules.__m[$midx++].__ptr
set $mname = (uintptr_t)$module_ptr->module_name.__str.__m
set $maddr = (uintptr_t)$module_ptr->first_exec
printf "Loading %s at 0x%lx\n",$mname,$maddr
eval "add-symbol-file %s 0x%lx",$mname,$maddr
end
end
define allsyms
modulesyms
initsyms
end
define modulelist
set $midx = 0
set $mcount = loaded_modules.__sz
while $midx < $mcount
set $module_ptr = loaded_modules.__m[$midx++].__ptr
set $mname = (uintptr_t)$module_ptr->module_name.__str.__m
set $maddr = (uintptr_t)$module_ptr->first_exec
printf "0x%lx %s",$maddr,$mname
end
end
define stkusage
set $tidx = 0
while $tidx < cpu_count
if threads[$tidx].ctx != 0
set $stkst = threads[$tidx].stack
set $stsz = threads[$tidx].stack_size
set $stken = (unsigned long)$stkst + $stksz
set $tsp = threads[$tidx].ctx->gpr.iret.rsp
set $tsused = $stken - (unsigned long)$tsp
set $tsusage = 100 * $tsused / $tssz
printf "tid %d: %u/%uKB (%u%%)", $tidx, $tsused >> 10, $tssz >> 10, $tsusage
end
set $tidx = $tidx + 1
end
end
define dumptree
print $arg0.__current_size
# Go to first element
set $node = $arg0.__first
while $node != 0
if $argc == 2
set $item = $node->__storage.__instance
eval $arg1
else
print $node->__storage.__instance
end
if $node->__right != 0
set $node = $node->__right
# Keep going left until there is no left
while $node->__left != 0
set $node = $node->__left
end
else
# Keep going up until from left
while $node != 0
if $node->__parent && $node->__parent->__right == $node
set $node = $node->__parent
else
set $node = $node->__parent
loop_break
end
end
end
end
end
define cdd
c
monitor x /10i $cs.base+$eip
end
define ddd
monitor x /10i $cs.base+$eip
end
define sid
if $argc == 1
si $arg0
else
si
end
monitor x /10i $cs.base+$eip
end
define nid
if $argc == 1
ni $arg0
else
ni
end
monitor x /10i $cs.base+$eip
end
define stepirq
maintenance packet qqemu.sstep=1
end
define stepnoirq
maintenance packet qqemu.sstep=7
end