簡體   English   中英

在調用函數時使GDB打印控制流程

[英]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打印最后一幀的回溯(即它是當前函數)ccontinue的快捷方式,繼續執行,而end只是命令列表的分隔符。

注意 :如果您跟蹤庫函數,您可能希望等待lib加載。 例如,設置一個休息到main或任何功能,運行應用程序直到該點,然后只設置你想要的斷點。

使用正確的工具;)

如何在GDB中自動打印下N行?

你有沒有看到litb對這里類似帖子的出色表現?

他使用readelf來獲取有趣的符號,使用gdb命令來獲取跟蹤,並使用awk來粘合所有這些。

基本上你必須改變的是修改他的gdb命令腳本以從回溯中刪除1深度以查看堆棧和過濾特定函數,並使用awk / python /(...)腳本重新格式化輸出以將其呈現為樹。 (我承認我現在太懶了...)

您可以在批處理模式下調用gdb (使用-x選項),在需要的地方中斷並請求回溯( bt ),然后使用grepegrep過濾結果。

縮進比較困難,但是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM