這次快一個。GDB:自動'下一個?
是否有可能(除了永遠按下輸入)GDB不斷地通過一個程序next
找到一個錯誤發生的地方?
編輯:continue
是不是我想要的;我希望一行一行地有效地看到完整的程序執行情況,你會一遍又一遍地從next
中得到。
這次快一個。GDB:自動'下一個?
是否有可能(除了永遠按下輸入)GDB不斷地通過一個程序next
找到一個錯誤發生的地方?
編輯:continue
是不是我想要的;我希望一行一行地有效地看到完整的程序執行情況,你會一遍又一遍地從next
中得到。
這裏的東西是那這樣的黑客我有點不好意思地張貼。但是如果你只需要一次性的話,它可能足以讓你獲得你想要的信息。真的應該有更好的方法。
可以定義執行step
或next
命令一定數量的次愚蠢的小gdb的腳本:
# file: step_mult.gdb
define step_mult
set $step_mult_max = 1000
if $argc >= 1
set $step_mult_max = $arg0
end
set $step_mult_count = 0
while ($step_mult_count < $step_mult_max)
set $step_mult_count = $step_mult_count + 1
printf "step #%d\n", $step_mult_count
step
end
end
(我用的步驟,而不是next
對於沒有什麼特別好的理由,只是將其更改爲任何你需要。)
然後你可以運行該命令(可選計數),它會很好地顯示每個step
或next
。
下面是一個示例程序,當它試圖取消引用一個NULL指針會崩潰:
#include<stdio.h>
int x[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8,9, 10
};
int* p[11];
int main()
{
int i;
for (i = 0; i < 11; ++i) {
p[i] = &x[i];
}
p[5] = 0;
for (i = 0; i < 11; ++i) {
printf("*p[%d] == %d\n", i, *p[i]);
}
return 0;
}
這裏有一個GDB會話(在Windows上)調試程序並使用step_mult
腳本:
C:\temp>gdb test.exe
GNU gdb (GDB) 7.2
...
Reading symbols from C:\temp/test.exe...done.
(gdb) source c:/temp/step_mult.gdb
(gdb) start
Temporary breakpoint 1 at 0x401385: file C:\temp\test.c, line 23.
Starting program: C:\temp/test.exe
[New Thread 5396.0x1638]
Temporary breakpoint 1, main() at C:\temp\test.c:23
23 for (i = 0; i < 11; ++i) {
(gdb) step_mult 70
step #1
24 p[i] = &x[i];
step #2
23 for (i = 0; i < 11; ++i) {
step #3
24 p[i] = &x[i];
step #4
23 for (i = 0; i < 11; ++i) {
step #5
24 p[i] = &x[i];
step #6
23 for (i = 0; i < 11; ++i) {
step #7
24 p[i] = &x[i];
step #8
23 for (i = 0; i < 11; ++i) {
step #9
24 p[i] = &x[i];
step #10
23 for (i = 0; i < 11; ++i) {
step #11
24 p[i] = &x[i];
step #12
23 for (i = 0; i < 11; ++i) {
step #13
24 p[i] = &x[i];
step #14
23 for (i = 0; i < 11; ++i) {
step #15
24 p[i] = &x[i];
step #16
23 for (i = 0; i < 11; ++i) {
step #17
24 p[i] = &x[i];
step #18
23 for (i = 0; i < 11; ++i) {
step #19
24 p[i] = &x[i];
step #20
23 for (i = 0; i < 11; ++i) {
step #21
24 p[i] = &x[i];
step #22
23 for (i = 0; i < 11; ++i) {
step #23
27 p[5] = 0;
step #24
29 for (i = 0; i < 11; ++i) {
step #25
30 printf("*p[%d] == %d\n", i, *p[i]);
step #26
*p[0] == 0
29 for (i = 0; i < 11; ++i) {
step #27
30 printf("*p[%d] == %d\n", i, *p[i]);
step #28
*p[1] == 1
29 for (i = 0; i < 11; ++i) {
step #29
30 printf("*p[%d] == %d\n", i, *p[i]);
step #30
*p[2] == 2
29 for (i = 0; i < 11; ++i) {
step #31
30 printf("*p[%d] == %d\n", i, *p[i]);
step #32
*p[3] == 3
29 for (i = 0; i < 11; ++i) {
step #33
30 printf("*p[%d] == %d\n", i, *p[i]);
step #34
*p[4] == 4
29 for (i = 0; i < 11; ++i) {
step #35
30 printf("*p[%d] == %d\n", i, *p[i]);
step #36
Program received signal SIGSEGV, Segmentation fault.
0x004013d2 in main() at C:\temp\test.c:30
30 printf("*p[%d] == %d\n", i, *p[i]);
step #37
Program received signal SIGSEGV, Segmentation fault.
0x004013d2 in main() at C:\temp\test.c:30
30 printf("*p[%d] == %d\n", i, *p[i]);
step #38
Program exited with code 030000000005.
step #39
The program is not being run.
(gdb)
不幸的是,由於腳本不會在段錯誤發生時停止,所以gdb決定停止調試程序,所以你不能進行任何其他有用的查詢。但日誌可能仍然有用。
我確信有很多方法可以使腳本更加智能化。不幸的是,我不知道該怎麼做,而且GDB的用戶級別文檔似乎對這些細節沒有太大的幫助。最好的方法是,如果腳本能夠檢測到段錯誤或信號發生,那麼就停下來,而不是依賴任意數量。我想象gdb/MI接口,或者甚至Python腳本接口可能有一個很好的機制,但我對這些並不知情。
第一次運行後,您可以使用顯示的計數(在我的示例中爲37),然後重新啓動程序並給出一個計數,它只是在之前崩潰的位置處進行計數,然後手動進行控制。
就像我說的,it's not particularly pretty - but it might get you there。
感謝@Michael Burr - 受到那個啓發,並且只想發佈一個鏈接到類似的Python代碼[GDB auto步進 - 自動打印行,而自由運行?](http://stackoverflow.com/questions/6947389/gdb-auto-stepping-automatic-printout-of-lines-while-free-running/6964213#6964213)。 ..乾杯! – sdaau 2011-08-06 01:37:40
今天有更漂亮的方式嗎? – 2015-09-13 20:33:28
您可以使用continue
或c
繼續執行到下一個斷點。
另請參閱Run an Application in GDB Until an Exception Occurs (StackOverflow)關於如何設置「catchpoint」,這將引發異常時中斷執行。
continue
命令將運行,直到發生斷點,應用程序導致異常(即崩潰)或應用程序終止。
或直到你Ctrl + C(它暫停執行) – 2011-05-01 02:25:59
另請參閱這篇文章:c - GDB auto stepping - automatic printout of lines, while free running?,它使用gdb的python接口。
gdb應該如何知道它何時碰到錯誤?什麼改變? – 2011-04-28 00:59:55
坦率地說,它段錯誤:) – Bolster 2011-04-28 01:30:36