2012-05-25 33 views
49

GDB có được xây dựng trong cơ chế kịch bản hay không, tôi có nên viết mã một kịch bản mong đợi hay không, hoặc có giải pháp nào tốt hơn không?Cách tốt nhất để tự động hóa phiên gỡ lỗi GDB là gì?

Tôi sẽ gửi cùng một chuỗi lệnh mỗi lần và tôi sẽ lưu đầu ra của từng lệnh vào tệp (có khả năng nhất bằng cách sử dụng cơ chế ghi tích hợp sẵn của GDB, trừ khi ai đó có ý tưởng tốt hơn).

+0

tập hợp con: http://stackoverflow.com/questions/13935443/gdb-scripting-execute-commands-at-selected- breakpoint –

Trả lời

43

gdb thực thi tệp .gdbinit sau khi chạy. Vì vậy, bạn có thể thêm các lệnh của mình vào tệp này và xem liệu nó có phù hợp với bạn hay không. Đây là một ví dụ về .gdbinit để in vết lùi cho tất cả các cuộc gọi f():

set pagination off 
set logging file gdb.txt 
set logging on 
file a.out 
b f 
commands 
bt 
continue 
end 
info breakpoints 
r 
set logging off 
quit 
+1

Có biến môi trường nào tôi có thể đặt để GDB có thể chạy một tệp khác khi khởi động không? – Anonymous

+18

@ Không đồng nghĩa, nhưng có một tùy chọn dòng lệnh: --command = FILE, -x Thực hiện các lệnh GDB từ FILE. – matt

64

Tôi chỉ đi qua một cái gì đó tương tự, và đã đưa ra một ví dụ cơ bản - và biết tôi sẽ quên nó đi sớm, Tôi nghĩ rằng tôi nên đăng nó :) Vì vậy, tôi sẽ đăng nó ở đây, vì nó có vẻ liên quan đến câu hỏi.

Về cơ bản, trong ví dụ này, tôi muốn nhận được một số giá trị biến ở những vị trí cụ thể của mã; và có chúng cho đến khi chương trình bị treo. Vì vậy, đây là lần đầu tiên một chương trình nhỏ mà là guaranteed to crash trong một vài bước, test.c:

#include <stdio.h> 
#include <stdlib.h> 

int icount = 1; // default value 

main(int argc, char *argv[]) 
{ 
    int i; 

    if (argc == 2) { 
    icount = atoi(argv[1]); 
    } 

    i = icount; 
    while (i > -1) { 
    int b = 5/i; 
    printf(" 5/%d = %d \n", i, b); 
    i = i - 1; 
    } 

    printf("Finished\n"); 
    return 0; 
} 

Lý do duy nhất chương trình chấp nhận đối số dòng lệnh là để có thể chọn số lượng các bước trước khi đâm - và để hiển thị rằng gdb bỏ qua --args ở chế độ hàng loạt. Này tôi biên dịch với:

gcc -g test.c -o test.exe 

Sau đó, tôi chuẩn bị kịch bản sau đây - lừa chính ở đây là gán một command cho mỗi breakpoint, mà cuối cùng sẽ continue (xem thêm Automate gdb: show backtrace at every call to function puts). Kịch bản này tôi gọi test.gdb:

# http://sourceware.org/gdb/wiki/FAQ: to disable the 
# "---Type <return> to continue, or q <return> to quit---" 
# in batch mode: 
set width 0 
set height 0 
set verbose off 

# at entry point - cmd1 
b main 
commands 1 
    print argc 
    continue 
end 

# printf line - cmd2 
b test.c:17 
commands 2 
    p i 
    p b 
    continue 
end 

# int b = line - cmd3 
b test.c:16 
commands 3 
    p i 
    p b 
    continue 
end 

# show arguments for program 
show args 
printf "Note, however: in batch mode, arguments will be ignored!\n" 

# note: even if arguments are shown; 
# must specify cmdline arg for "run" 
# when running in batch mode! (then they are ignored) 
# below, we specify command line argument "2": 
run 2  # run 

#start # alternative to run: runs to main, and stops 
#continue 

Lưu ý rằng, nếu bạn có ý định sử dụng nó trong chế độ hàng loạt, bạn phải "khởi động" kịch bản cuối cùng, với run hoặc start hoặc một cái gì đó tương tự.

Với kịch bản này tại chỗ, tôi có thể gọi gdb trong chế độ hàng loạt - mà sẽ tạo ra kết quả như sau trong terminal:

$ gdb --batch --command=test.gdb --args ./test.exe 5 
Breakpoint 1 at 0x804844d: file test.c, line 10. 
Breakpoint 2 at 0x8048485: file test.c, line 17. 
Breakpoint 3 at 0x8048473: file test.c, line 16. 
Argument list to give program being debugged when it is started is "5". 
Note, however: in batch mode, arguments will be ignored! 

Breakpoint 1, main (argc=2, argv=0xbffff424) at test.c:10 
10 if (argc == 2) { 
$1 = 2 

Breakpoint 3, main (argc=2, argv=0xbffff424) at test.c:16 
16  int b = 5/i; 
$2 = 2 
$3 = 134513899 

Breakpoint 2, main (argc=2, argv=0xbffff424) at test.c:17 
17  printf(" 5/%d = %d \n", i, b); 
$4 = 2 
$5 = 2 
5/2 = 2 

Breakpoint 3, main (argc=2, argv=0xbffff424) at test.c:16 
16  int b = 5/i; 
$6 = 1 
$7 = 2 

Breakpoint 2, main (argc=2, argv=0xbffff424) at test.c:17 
17  printf(" 5/%d = %d \n", i, b); 
$8 = 1 
$9 = 5 
5/1 = 5 

Breakpoint 3, main (argc=2, argv=0xbffff424) at test.c:16 
16  int b = 5/i; 
$10 = 0 
$11 = 5 

Program received signal SIGFPE, Arithmetic exception. 
0x0804847d in main (argc=2, argv=0xbffff424) at test.c:16 
16  int b = 5/i; 

Lưu ý rằng trong khi chúng tôi chỉ định đối số dòng lệnh 5, vòng lặp vẫn chỉ quay hai lần (như là đặc điểm kỹ thuật của run trong tập lệnh gdb); nếu run không có bất kỳ đối số nào, nó chỉ quay một lần (giá trị mặc định của chương trình) xác nhận rằng --args ./test.exe 5 bị bỏ qua.

Tuy nhiên, kể từ bây giờ đây là đầu ra trong một cuộc gọi duy nhất, và không có bất kỳ tương tác người dùng, sản lượng dòng lệnh có thể dễ dàng bị bắt giữ trong một file văn bản sử dụng bash chuyển hướng, nói:

gdb --batch --command=test.gdb --args ./test.exe 5 > out.txt 

Ngoài ra còn có ví dụ về cách sử dụng python để tự động hóa gdb trong c - GDB auto stepping - automatic printout of lines, while free running?

Hy vọng điều này sẽ giúp,
Chúc mừng!

+3

Cảm ơn bạn đã chia sẻ, điều này hữu ích –

+1

quá lỗi đối với tôi. 'detach' trong' command' làm cho 'gdb' crash,' continue' trong 'coammand' kết quả trong các cảnh báo' Selected thread is running.' lạ. – Blauhirn

1

Nếu a -x có tệp quá nhiều đối với bạn, chỉ cần sử dụng multiple -ex's. Đây là một ví dụ để theo dõi một chương trình chạy cho thấy (và tiết kiệm) những vết lùi về tai nạn

sudo gdb -p $(pidof my-app) -batch \ 
    -ex "set logging on" \ 
    -ex continue \ 
    -ex "bt full" \ 
    -ex quit 
Các vấn đề liên quan