環境: arm64-ubuntu
相關:strace、ltrace、readelf、patchelf、strings、ldd? -v
1). 使用 gdb 啟動目標程序(不能直接用gdb啟動的,可以先單獨啟動,再?gdb attach 強制調試)
DIR_APP=/opt/test
gdb --args env LANGUAGE= LD_LIBRARY_PATH=${DIR_APP}:${DIR_APP}/addons/cef:${DIR_APP}/old-libs ${DIR_APP}/main
2). gdb 指令
gdb載入目標程序后會自動暫停程序的運行,要繼續運行程序得敲:
r? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # run
q? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# quit, 退出 gdb,停止調試但在運行之前,可能需要先靜態分析下,好設置斷點,設置斷點的gdb指令:
b? ? ?*0x7ff43b8254 ? ? ? ? ? # 在指定地址下斷, breakpoint
b? ? ? uv_fs_mkdir? ? ? ? ? ? ??# 如果有函數名這種明確的調試符號,可以直接在函數入口處下斷,即設置斷點
b? ? ? __libc_start_main
斷點被觸發后,gdb會暫停程序,此時如要繼續運行,得敲入:
c? ? ? ? #?或者其它的繼續運行指令, 如單步運行 si、ni,運行到函數結束 finish
反匯編指定地址的代碼:
x? ? ? ? ? ?/20i 0x0000007ff43b3a90? ? ? #?examine,用于解析指定內存地址的數據,可通過選項來決定是解析為匯編指令還是指定格式的數據
display /20i $pc
disp? ? ? /20i $pc
暫停時自動反匯編的開關打開:
set disassemble-next-line auto
顯示當前的函數調用棧:
bt
bt full
顯示指定地址的內存:
dump binary memory ./test.so 0x0000007ff4360000 0x0000007ff43e3288
x? ? /20x? ? 0x0000007ff4360000
p (char*)0x7fffffcdb9
顯示寄存器值
i? ? ? ? registers
p? ? ? $pc
print $pc
顯示各個庫都被加載到內存哪個地方(可用于在靜態分析工具,如ida中設置段基址:? edit -> segment -> rebase):
info proc mappings? ? ? ? #?這個才是準確的, info sharelibrary(i? sh) 顯示的是可執行區的內存起始地址
單步跟蹤:
si ?會進函數(有調試符號可以不用加i)
ni ?不進函數
?執行到當前函數結束處
finish
?
3). gdb 多線程相關的調試
info threads????????# 顯示所有線程
thread n??????????????# 切換到指定線程
set scheduler-locking on ? ?# 只運行當前線程
4). 斷點以外的其它打斷方式?
catch exception
catch assert
catch catch
catch signal 6? ?# linux信號攔截也可以打斷目標程序的運行
catch signal 11 # SIGSEGV,這個攔截打斷類型,對軟件在新平臺運行報錯的排查有用
? ? ? ? ? ? ? ? ? ? ? ? ?# 能準確定位到哪個庫中的哪個函數中的哪條CPU指令!