Try   HackMD

GDB Python Integration

tags: gdb python elf mingnus

contributed by <mingnus>

Basics

  • One-line Python code in gdb breakpoint command
    • 案例: 計算 breakpoint hit 次數 (雖說 gdb 本身就會計算 breakpoint hit count)
(gdb) command 1
>silent
>python global i; i=0
>cont
>end

(gdb) command 2
>silent
>python global i; i+=1
>cont
>end

(gdb) command 3
>silent
>python global i; print("counter={}".format(i))
>cont
>end

GDB Python API 應用案例

  • supertrace.py
    以 gdb Python API 提供的 stack frame 功能追踪程式執行時的 call stack, 進而印出 call graph, 對於追踪單一執行緒滿有幫助。程式存在以下缺失:

    • supertrace.py 載入方式: supertrace.gdbpy 必須和 debuggee 置於相同目錄
    • Shared lib symbols 讀取方式及 file list 取得方式的缺陷: 為了讀取 shared lib symbols, supertrace 的做法是執行 debuggee, 讓程式自動載入 shared libs 後才使用 rbreak 設定 breakpoints。副作用是其他非相關 symbols 也會被設立 breakpoints,例如 debug 版 libc, 導致 supertrace.gdb 準備時間變很長
    • 無法控制哪些 symbol 要設定 breakpoint, 也難以有效增減 breakpoints
    • 輸出格式可再加強, 例如增加 function parameters
    • Stack 追踪方式無法處理迴圈呼叫
    • Breakpoint commands 可改用 Python API gdb.Breakpoint 實作
  • callgraph on GitHub
    本專案未使用 gdb Python API, 而是用 awk 後製 gdb output, 所以速度差了一截。另外它僅印出 caller 及 callee, 而非像 supertrace 那樣追踪整個 call stack

改善 supertrace

source code

使用方法: gdb 直接載入 supertrace.py 即可

(gdb) python sys.path.insert(0, '<path_to_supertrace.py>'); import supertrace

 or

(gdb) set script-extension soft
(gdb) source supertrace.py

改善項目

  • 加強程式獨立性, 不需依賴 supertrace.gdb
  • 新增 tracepoint 設定指令
    • breakfile: 追踪單一檔案內的所有 fucntion
    • breaksymbol: 追踪特定 function
  • 以 gdb.Breakpoint 取代 breakpoint commands

問題

  • 如何用 gdb Python API 取得一個 source file 裡的所有 symbols
    rbreak 使用 search_symbols() (in gdb/symtab.c) 取得 symbols, 但 gdb Python API 僅提供 gdb.lookup_symbol() (對應 lookup_symbol() in gdb/symtab.c), 必須提供明確 symbol name。似乎要用 gdb.Block iteration 解決, 但這功能似乎還沒完成

    gdb provides a method to get a block's superblock, but there is currently no way to examine the sub-blocks of a block, or to iterate over all the blocks in a symbol table