2017-05-10 113 views
0

我很難找出這一個;我有一個程序,iverilog執行system()調用調用另一個程序,ivl。我想在gdb中調試第二個程序ivl,但是當我用父進程調用gdb時,我無法讓gdb在子進程中設置任何斷點。以下是程序的外觀:gdb進入子進程時中斷

//iverilog-main.cpp (Parent process) 

int main(){ 
    //... 
    system("ivl arg1 arg2"); 
    //... 
    return 0; 
} 

//ivl-main.cpp (child process) 

int main(){ 
    //... 
    //stuff I want to debug 
    //... 
    return 0; 
} 

我跑GDB的命令是:gdb iverilog -x cmds.gdb

# cmds.gdb 
set args hello.v 
set follow-fork-mode child 
set breakpoint pending on 
break ivl-main.cpp:main 
run 

不幸的是,GDB不會在ivl-main.cpp:main突破,它只是完成而沒有斷裂;輸出我得到的是:

Starting program: /usr/local/bin/iverilog hello.v 
[New process 18117] 
process 18117 is executing new program: /bin/dash 
[Inferior 2 (process 18117) exited normally] 

我敢肯定ivl-main.cpp:main被調用,因爲當我在gdb運行ivl程序成功地打破了那裏。

我的想法是gdb在運行gdb iverilog時不會將ivl-main.cpp識別爲源文件,並且它在進入包含ivl-main.cpp作爲源的子進程時未設置該斷點文件。所以我認爲如果我在gdb進入子進程時爲ivl-main.cpp設置斷點,它應該可以工作。我能想到的唯一方法是在system()調用中手動中斷並進入子進程,然後設置斷點。有沒有一種更優雅的方法可以在進入子進程時強制gdb破壞?

回答

1

This answer提供達到你想要的東西的一種方式。

理論上,set follow-fork-mode child應該工作。

在實踐中,iverilog可能本身運行shell腳本(fork S)多個命令,所以在每一個fork你需要決定是否要繼續調試父母或子女。一個錯誤的決定,你已經失去了控制最終執行你的程序的過程。這很可能解釋了爲什麼它不適合你。

+0

你是對的,'system()'調用調用了多個程序,我感興趣的並不是第一個,所以gdb會跟着第一個下一個,當它完成時停止。當我通過'劣等2'完成時,我能夠通過切換到另一個劣勢來解決這個問題。謝謝! – mtveezy

1

通常情況下,GDB一次只能調試一個進程 - 如果你的程序分叉,那麼你將調試父進程或子進程,但不是同時進行。默認情況下,GDB繼續叉子後調試的父母,但你可以改變這種行爲,如果你這樣用下面的命令的願望:

set follow-fork-mode child

或者,你可以告訴GDB,以保持雙方的父母和孩子在其控制之下。默認情況下,GDB只是跟隨一個過程,但你可以告訴它遵循所有的子進程用這個命令:

set detach-on-fork off

GDB是指每個調試的進程爲「劣等」。在調試多個進程時,您可以使用「inferiors」命令檢查每個進程並與其進行交互,這與您使用「線程」檢查或與多個線程交互的方式類似。

查看更多文檔瀏覽:

https://sourceware.org/gdb/onlinedocs/gdb/Forks.html

+0

我已經使用過'set fork-follow-mode child',但gdb仍然無法在「劣勢」過程中設置斷點。 – mtveezy

+0

是否有可能你的系統呼叫失敗,叉子沒有發生?你所需要做的就是設置'follow-fork-mode child'和'break main',並且在每次調用它遇到的一個「main」函數時GDB都會中斷。你甚至不需要設置你想破解的特定源代碼文件(甚至還沒有加載的文件)。 – David

+0

gdb 8.0-20.fc26可識別follow-fork-mode,而不是fork-follow-mode。 –