我有一個簡單的 C 程式(如下所示),它在一個回圈中呼叫一個函式g5 次,在函式內部g,它在一個回圈中呼叫f10 次(所以f總共呼叫了 50 次)。我正在嘗試撰寫一個gdb腳本(如下所示):
- 在
g - 運行直到
g第一次被呼叫 - 為斷點 in 設定斷點命令,
g以便下次g到達斷點 in 時gdb退出 - 在函式中設定斷點
f - 進入一個while回圈,每次
f到達時都會做一些事情,然后繼續(這必須是一個while回圈而不是一組斷點命令,因為這是一個更復雜情況的最小示例,我有多個step/finish/continue每次到達內部函式中的斷點時發出命令,這是斷點命令所不能做到的)
我觀察到的f是到達了內部函式的斷點,但是當第二次gdb到達斷點g時,它沒有執行我設定的命令g(IEgdb沒有退出)。程式繼續執行并繼續到下一次f呼叫該函式時,即使我info break在gdb提示符下鍵入,gdb顯示我為斷點設定的命令g。
我的問題:
- 為什么我在函式中的斷點命令
g沒有被執行,即使gdb每次到達斷點時都會列印出來g,并info break列印出與相關的命令g? - 如何更改我的
gdb腳本,以便g在第二次到達斷點時gdb退出? - 也許,作為上一個問題的解決方案,是否有某種方法可以檢查在while回圈中到達了哪個斷點,如果它是中的斷點則退出
g?
以下是我的簡單 C 程式和gdb腳本:
簡單的 C 程式
#include <stdio.h>
int i = 0;
void f() {
printf("in f(), i = %i\n", i );
}
void g() {
printf("in g()\n");
for (int j = 0; j < 10; j ) {
f();
}
}
int main() {
for (int j = 0; j < 5; j ) {
g();
}
}
gdb 腳本
break g
run
delete
break g
commands
printf "gdb: in g\n"
quit
end
break f
continue
while 1
printf "gdb: in f\n"
continue
end
uj5u.com熱心網友回復:
- 如何更改我的 gdb 腳本,以便當第二次到達 g 中的斷點時,gdb 退出?
您可以使用此blah.txt腳本檔案:
break g
ignore 1 1
run
quit
y
這基本上是在說:
- 打破
g功能。 - 忽略該斷點 1 次。
- 運行程式。
- 退出。
- 是的,我真的很想辭職。
使用以下命令構建您的blah.c檔案:gcc -g -o blah blah.c
運行它: gdb -x blah.txt blah
輸出:
Breakpoint 1 at 0x1196: file blah.c, line 9.
in g()
in f(), i = 0
in f(), i = 1
in f(), i = 2
in f(), i = 3
in f(), i = 4
in f(), i = 5
in f(), i = 6
in f(), i = 7
in f(), i = 8
in f(), i = 9
Breakpoint 1, g () at blah.c:9
9 void g() {
A debugging session is active.
Inferior 1 [process 181] will be killed.
Quit anyway? (y or n) [answered Y; input not from terminal]
如果您想在遇到斷點時做一些作業,這個其他腳本可能會起作用f:g
- 將布爾標志 , 設定
break_g_hit_before為 false。 - 將斷點的命令集定義
g為:
print I'm ing;
檢查是否break_g_hit_before為真,在這種情況下,退出 gdb;
否則,設定break_g_hit_before為 true,然后繼續。 - 將斷點的命令集定義
f為:列印我在f并繼續。 - 跑。
set $break_g_hit_before = 0
break g
commands
printf "*** gdb: in g\n"
if $break_g_hit_before
quit
y
end
set $break_g_hit_before = 1
continue
end
break f
commands
printf "### gdb: in f\n"
continue
end
run
輸出:
Breakpoint 1 at 0x1196: file blah.c, line 9.
Breakpoint 2 at 0x1169: file blah.c, line 5.
Breakpoint 1, g () at blah.c:9
9 void g() {
*** gdb: in g
in g()
Breakpoint 2, f () at blah.c:5
5 void f() {
### gdb: in f
in f(), i = 0
Breakpoint 2, f () at blah.c:5
5 void f() {
### gdb: in f
in f(), i = 1
Breakpoint 2, f () at blah.c:5
5 void f() {
### gdb: in f
in f(), i = 2
Breakpoint 2, f () at blah.c:5
5 void f() {
### gdb: in f
in f(), i = 3
Breakpoint 2, f () at blah.c:5
5 void f() {
### gdb: in f
in f(), i = 4
Breakpoint 2, f () at blah.c:5
5 void f() {
### gdb: in f
in f(), i = 5
Breakpoint 2, f () at blah.c:5
5 void f() {
### gdb: in f
in f(), i = 6
Breakpoint 2, f () at blah.c:5
5 void f() {
### gdb: in f
in f(), i = 7
Breakpoint 2, f () at blah.c:5
5 void f() {
### gdb: in f
in f(), i = 8
Breakpoint 2, f () at blah.c:5
5 void f() {
### gdb: in f
in f(), i = 9
Breakpoint 1, g () at blah.c:9
9 void g() {
*** gdb: in g
A debugging session is active.
Inferior 1 [process 219] will be killed.
Quit anyway? (y or n) [answered Y; input not from terminal]
uj5u.com熱心網友回復:
我有一個有點駭人聽聞的解決方案,它適用于這種情況(也適用于我感興趣的更復雜的情況,上面的問題是一個最小的可重現示例)。但它不一定在所有情況下都有效,例如,當更高的堆疊幀中沒有有效的計數器變數時,所以我將在此處發布但不接受它作為答案,同時等待更通用的解決方案.
訣竅如下:在 while 回圈開始時,向上堆疊幀并查看函式中的j計數器變數,然后立即main退出(這意味著它已被多次呼叫)。示例腳本:gdbj > 0ggdb
break g
run
delete
break f
continue
while 1
printf "gdb: in f\n"
frame function main
if j > 0
quit
end
continue
end
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/417816.html
標籤:
