[英]Make GDB print control flow of functions as they are called
如何調用感興趣的gdb打印函數,根據堆棧的深度縮進?
我希望能夠說出(制作):
(gdb) trace Foo* Bar* printf
並讓gdb打印所有以Foo或Bar開頭的函數,因為它們被調用。 有點像gnu cflow,除了使用調試符號和僅實際調用的打印函數,而不是所有可能的調用流。
無法幫助的工具包括cachegrind,callgrind和oprofile,它們最常調用函數的結果。 我需要保留的調用順序。
通配符(或等效的)是必不可少的,因為有很多Foo和Bar函數。 雖然我願意完全記錄所有功能。 或者,也許告訴gdb記錄特定庫中的所有函數。
某些GDB向導必須有一個用於此常見作業的腳本!
在您的情況下,我將轉向gdb中的define
命令,它允許您定義一個函數,該函數最多可以包含10個參數。
您可以將函數名稱傳遞給“trace”作為您定義的函數的參數,或者將它們全部記錄在函數本身中。 我會做類似以下的事情
define functiontrace
if $arg0
break $arg0
commands
where
continue
end
end
if $arg1
...
gdb中用戶定義函數的參數引用為$ arg0- $ arg9。 或者,您可以在函數中記錄要跟蹤的每個函數,而不是使用$ arg0-9。
注意:這不會縮進堆棧跟蹤中的深度,但每次調用函數時都會打印堆棧跟蹤。 我發現這種方法比strace等更有用...因為它會記錄你想要的任何函數,系統,庫,本地或其他。
有一個rbreak
cmd接受用於設置斷點的正則表達式。 您可以使用:
(gdb) rbreak Foo.*
(gdb) rbreak Bar.*
(gdb) break printf
然后使用commands
打印調用的每個函數。 例如,讓α=最后一個斷點的編號(您可以檢查它與i br
如果你錯過了),然后執行:
(gdb) commands 1-α
Type commands for breakpoint(s) 1-α, one per line.
End with a line saying just "end".
>silent
>bt 1
>c
>end
(gdb)
一些細化: silent
抑制不必要的信息消息, bt 1
打印最后一幀的回溯(即它是當前函數) , c
是continue
的快捷方式,繼續執行,而end
只是命令列表的分隔符。
注意 :如果您跟蹤庫函數,您可能希望等待lib加載。 例如,設置一個休息到main
或任何功能,運行應用程序直到該點,然后只設置你想要的斷點。
使用正確的工具;)
你有沒有看到litb對這里類似帖子的出色表現?
他使用readelf來獲取有趣的符號,使用gdb命令來獲取跟蹤,並使用awk來粘合所有這些。
基本上你必須改變的是修改他的gdb命令腳本以從回溯中刪除1深度以查看堆棧和過濾特定函數,並使用awk / python /(...)腳本重新格式化輸出以將其呈現為樹。 (我承認我現在太懶了...)
您可以在批處理模式下調用gdb
(使用-x
選項),在需要的地方中斷並請求回溯( bt
),然后使用grep
或egrep
過濾結果。
縮進比較困難,但是bt
輸出是有序的,所以你在軌跡頂部有一個當前函數,而在最底部有main
函數。
所以你用命令創建文件:
br <function name where to break>
run
bt
kill
quit
然后運行gdb <program> -x<command file>
過濾以#<digit>
開頭的字符串 - 您將獲得堆棧跟蹤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.