動機
之前不常用記錄一下
basic
- 印
- 變數val:
print(p) {var}- 追蹤var(step每次都印):
display {var}
- 追蹤var(step每次都印):
- 變數type:
whatis {var} - code:
list(l) - 資訊:
info ??- break
- 下面hook的list
- threads
thread {thread-id}: 換到某個thread去
- forks
fork {fork-id}: 換到某個proc去
- share
- locals
- args
- reg / all-regs
- break
- 變數val:
- 跑:
run - 離開gdb:
quit(q) - 設定gdb參數:
set {key} {val} - kill:
kill [sig] - 處理gdb收到的sig:
handle {sig} nostop noprint ...
hook
- breakpoint(b)
- 設定:
b {addr} or {funcname} or {filename:line-num}- 條件成立才設:
b {pat} if exprb main.cpp:255 if strA.compare(strB) != 0
- 條件成立才設:
- 設定:
- watchpoint
- 設定在??時中斷:
- 寫:
watch {expr} - 讀:
rwatch {expr} - 寫或讀:
awatch {expr}
- 寫:
- 設定在??時中斷:
- catchpoint
- 中斷一次就好:
tcatch {??} - 設定在??發生時中斷:
catch {??}- throw
- catch
- exec/fork/vfork
- load/unload libname
- 中斷一次就好:
- 操作hook
- 啟用/停用:
enable/disable - 刪br:
clear(delete) - 繼續跑:
continue - 先不要跑:
ignore {br_id} num - 跑到br就做下面的事:
commands {br_id} ... end一行一個指令command 1print param2print param3->member1continueend
- 啟用/停用:
對stack與function上下其手
- stack
- 現在整個stack:
bt - 上一層:
up [num] - 下一層:
down - 現在這一層:
frame [num]- 單行執行:
stepornext - 把loop跑完:
until - 直接return:
return - 把frame跑完:
finish
- 單行執行:
- 現在整個stack:
- 我就是要跳:
jump {addr} or {filename:line-num}
reg, addr, signal
- addr -> val
- examine(x):
x/{COUNT}{FMT}{SIZE} {ADDRESS}- FMT: octal(o), hex(h), decimal(d) …
- SIZE: byte(b), word(w), giant(g)
- examine(x):
- 看reg:
${reg} handle {SIG} {ACT}- SIG: SIGHUP, SIGINT, …
- 可以看
shell kill -l
- 可以看
- ACT: 收到SIG時,做什麼,不要就是前面加no(
nostop)- stop: 程式停下來
- print: 印出這個SIG
- pass: relay SIG到被觀察的程式 (選no就是會sig被擋掉,因為沒有relay過去)
- SIG: SIGHUP, SIGINT, …
core dump
生core dump
ulimit -c unlimited
cat /proc/sys/kernel/core_pattern
echo “1” > /proc/sys/kernel/core_uses_pid # 我不想打proc name
使用core dump
gdb {proc-path} {coredump}gdb -c {coredump}- 如果有開core_uses_pid
script
- 自訂function:
define {func-name} ... end - 引入script:
source {path} - 變數:
set ${var} = {val}
gdbserver
兩邊準備同一個與source code 之後就可以透過server在client的gdb做除錯
gdbserver localhost:8888 prog
target remote 192.168.81.173:8888 prog
複習asm與debug
Assembly And The Art Of Debugging
reverse debug的範例
假設有一個程式多跑幾次就會seg fault
- 讓他在gdb一直跑
b main # main的b
b _exit # 最後一行的b
command 1
record
continue
end
command 2
run
end
- 爆了,看pc現在指到哪
p $pc # 假設是 (void (*))0x5e4c5d00
p/x $*0x5e4c5d00 # 試著拿值看看,應該是不行
- 開始往後追
reverse-stepi # 往後
disassemble # 現在在跑什麼,假設發現,是最後的return發生問題
p $sp # (void *) 0x7fffffffdc98 出事的addr
watch *(long**)0x7fffffffdc98 # 有人動了就停下來
reverse-continue # 往後,等停下來就是出事的位置
Ref
How to get a core dump for a segfault on Linux How to Debug Programs on Remote Server using GDBServer Example Scripting GDB GDB實用教學:自動化你的debug