[英]Both GDB and LLDB failing to reliably execute breakpoint commands in simple C file
作為研究項目的一部分,我試圖編寫一個gdb命令文件,該文件將在任意C源文件中的每一行代碼上輸出某些信息,直到程序終止。 這似乎可以通過while循環輕松實現,在循環內輸出我想要的任何數據,然后在循環結束時調用“ next”。 (我知道我希望“步驟”輸入函數調用;此刻我不擔心。)
但是,除了我在每一行輸出的數據外,我還想在某些斷點處執行特殊命令。 這似乎很容易通過“命令”完成。 但是,我遇到了while循環和斷點命令都不起作用的問題。
這是我用於測試的極其簡單的C文件:
int global;
int main() {
int x;
x=-1;
global = 5;
return(0);
}
我用gcc -g -o simple simple.c
編譯它。 然后,我運行gdb -x commands.txt
。 如果commands.txt的內容如下:
set confirm off
exec-file simple
file simple
set logging file gdb_output.txt
set logging on
set pagination off
#Special commands I want to execute on certain breakpoints
break 5
command
echo COMMAND 1 ACTIVATED\n
end
break 6
command
echo COMMAND 2 ACTIVATED\n
end
break 7
command
echo COMMAND 3 ACTIVATED\n
end
run
next
next
next
continue
quit
...然后gdb_output.txt的內容如下所示:
Breakpoint 1 at 0x4004da: file simple.c, line 5.
Breakpoint 2 at 0x4004e1: file simple.c, line 6.
Breakpoint 3 at 0x4004eb: file simple.c, line 7.
Breakpoint 1, main () at simple.c:5
5 x=-1;
COMMAND 1 ACTIVATED
Breakpoint 2, main () at simple.c:6
6 global = 5;
COMMAND 2 ACTIVATED
Breakpoint 3, main () at simple.c:7
7 return(0);
COMMAND 3 ACTIVATED
8 }
[Inferior 1 (process 29631) exited normally]
但是,如果我編輯命令文件以嘗試作為循環執行,則替換
next
next
next
continue
與
while true
next
end
但是讓腳本的其余部分完全相同,那么我為第6和7行的斷點指定的命令將永遠不會執行,運行修改后的命令文件后,gdb_output.txt的內容證明了這一點:
Breakpoint 1 at 0x4004da: file simple.c, line 5.
Breakpoint 2 at 0x4004e1: file simple.c, line 6.
Breakpoint 3 at 0x4004eb: file simple.c, line 7.
Breakpoint 1, main () at simple.c:5
5 x=-1;
COMMAND 1 ACTIVATED
Breakpoint 2, main () at simple.c:6
6 global = 5;
Breakpoint 3, main () at simple.c:7
7 return(0);
8 }
__libc_start_main (main=0x4004d6 <main()>, argc=1, argv=0x7fffffffe128, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe118) at ../csu/libc-start.c:325
325 ../csu/libc-start.c: No such file or directory.
[Inferior 1 (process 29652) exited normally]
commands.txt:30: Error in sourced command file:
The program is not being run.
我知道當前形式的循環是有問題的,因為它只會一直調用“ next”,直到程序終止(所以它永遠不會到達腳本底部的“ quit”),但這似乎不應該停止運行斷點命令-但這似乎正在發生。 being executed, I could condition my while loop to terminate once it hit breakpoints set before the C program's exit points.) (如果執行的斷點命令,我可以調節我的while循環終止,一旦它擊中了C程序的退出點之前設置斷點。)
這是GDB中的錯誤,還是我誤會了什么? 如果這種構造從根本上不起作用,那么有一種方法可以在程序運行的每個步驟上執行一系列固定的GDB命令,直到程序終止,同時還要執行在某些斷點處指定的命令-否則這基本上是不可能的一個GDB腳本?
(我的gdb版本是7.11.1,如果重要,我的操作系統是Linux。)
更新
我決定嘗試一下lldb並遇到一些更令人困惑的問題(使用與上述相同的C文件,並使用相同的命令編譯)。 這是我的lldb腳本:
target create --no-dependents --arch x86_64 simple
breakpoint set --file simple.c --line 5
breakpoint command add
script print "COMMAND 1 ACTIVATED"
DONE
breakpoint set --file simple.c --line 6
breakpoint command add
script print "COMMAND 2 ACTIVATED"
DONE
breakpoint set --file simple.c --line 7
breakpoint command add
script print "COMMAND 3 ACTIVATED"
DONE
run
frame variable x
continue
frame variable x
continue
frame variable x
continue
quit
這表現出相當奇怪的行為。 上面的版本到達第一個斷點,執行關聯的命令,然后忽略所有隨后的斷點。 如果僅注釋掉第二個斷點 ,其關聯的命令以及相應的frame variable x
,則continue
,則斷點1和3都會命中並執行其相應的命令。 僅注釋掉第一個或第三個斷點及其關聯的命令和frame variable x
, continue
只會導致第一個未注釋的斷點被命中,並且其關聯的命令將運行。 簡而言之,似乎在兩個連續的代碼行上都有斷點會導致第一個之后的所有斷點被忽略。
有人知道這是怎么回事嗎? 有沒有辦法讓我在每行上都有一個斷點並使它們都被擊中? 並且此問題與上述gdb問題有任何關系嗎?
我仍然沒有弄清楚為什么 gdb和lldb會按原樣運行,但是我確實設計了一種替代方法來實現我想要的功能。 我編寫了一個腳本,使用兩個命名管道與lldb進行通信,由此腳本的stdout鏈接到lldb的stdin,反之亦然,因此腳本可以發送lldb命令( frame variable -L
, bt
, step
等),然后獲取lldb的輸出並解析它。 該腳本當然可以循環所需的所有內容,因此可以繞過我無法使gdb或lldb命令文件正確循環的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.