Bắt GDB để lưu danh sách các điểm dừng


129

OK, ngắt thông tin liệt kê các điểm dừng, nhưng không ở định dạng sẽ hoạt động tốt với việc sử dụng lại chúng bằng cách sử dụng --command như trong câu hỏi này . GDB có phương pháp bỏ chúng vào một tệp có thể chấp nhận để nhập lại không? Đôi khi trong một phiên gỡ lỗi, cần phải khởi động lại GDB sau khi xây dựng một tập hợp các điểm dừng để kiểm tra.

Tệp .gdbinit có cùng vấn đề với --command. Lệnh ngắt thông tin không liệt kê các lệnh, mà là một bảng cho mức tiêu thụ của con người.

Để giải thích, đây là một mẫu từ thông tin phá vỡ :

(gdb) phá vỡ thông tin
Num Type Loại Enb Địa chỉ gì
1 điểm dừng giữ y 0x08048517 <foo :: bar (void) +7>

Câu trả lời:


204

Kể từ GDB 7.2 (2011-08-23), giờ đây bạn có thể sử dụng lệnh lưu điểm dừng .

save breakpoints <filename>
  Save all current breakpoint definitions to a file suitable for use
  in a later debugging session.  To read the saved breakpoint
  definitions, use the `source' command.

Sử dụng source <filename>để khôi phục các điểm dừng đã lưu từ tệp.


2
Điều gì về nếu họ là từ một tải lib chia sẻ? Nó trả lời N theo mặc định có vẻ như ...Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
bjackfly

2
@bjackfly sử dụng set breakpoint pending onnhư được mô tả trong cách trả lời Y trong tập lệnh gdb
--command

Lưu ý rằng khi bạn có một điều kiện điểm dừng không thể giải quyết khi khởi động ( break g_log if log_level==G_LOG_LEVEL_CRITICAL), thì ít nhất gdb 7.8.1 sẽ dừng phân tích cú pháp các lệnh tiếp theo. Nếu bạn có các lệnh bổ sung cần được thực thi cho điểm dừng đó, hãy đặt commandsdòng trướccondition dòng.
Lekensteyn

@Andry Tôi đã quay lại chỉnh sửa của bạn về blockquote ban đầu của tôi vì văn bản là một trích dẫn nguyên văn từ tài liệu ... Tôi sẽ đồng ý với chỉnh sửa của bạn nếu đó là từ của riêng tôi.
aculich

@aculich: Tôi hiểu rồi. Tôi sẽ khuyên bạn nên sử dụng kiểu trích dẫn hơn là kiểu mã trong mọi trường hợp.
Andry

26

Câu trả lời này đã lỗi thời. GDB hiện hỗ trợ tiết kiệm trực tiếp. Xem câu trả lời này .

Bạn có thể sử dụng đăng nhập:

(gdb) b main
Breakpoint 1 at 0x8049329
(gdb) info break
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x08049329 <main+16>
(gdb) set logging file breaks.txt
(gdb) set logging on
Copying output to breaks.txt.
(gdb) info break
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x08049329 <main+16>
(gdb) q

Tệp break.txt hiện chứa:

Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x08049329 <main+16>

Viết một tập lệnh AWK để chuyển đổi nó thành một định dạng hữu ích cho .gdbinithoặc một --commandtập tin thật dễ dàng. Hoặc thậm chí bạn có thể làm cho tập lệnh phát ra các dòng lệnh riêng biệt --eval-commandcủa GDB ...

Thêm macro nhỏ này vào .gdbinit sẽ giúp bạn làm điều đó:

# Call with dump_breaks file.txt
define dump_breaks
    set logging file $arg0
    set logging redirect on
    set logging on
    info breakpoints
    set logging off
    set logging redirect off
end

Người ta có thể dễ dàng sử dụng cắt và dán, nhưng phương pháp kịch bản có vẻ là cách để đi.
Casualcoder

1
Tôi không nghĩ rằng cắt và dán dễ dàng hơn là chỉ viết một kịch bản một lần, sau đó sử dụng nó một lần nữa :) sau tất cả, đó là lý do mà bạn đã hỏi câu hỏi này ngay từ đầu, tôi nghĩ :)
Johannes Schaub - litb

Ừm, ý tôi là sử dụng cắt và dán thay vì phương pháp ghi nhật ký. Kịch bản là nó cho đến nay chắc chắn.
Casualcoder

ồ gdb thất bại! Tôi sử dụng nó hàng ngày và yêu thích nhiều tính năng của nó. Nhưng thiếu chỉ là câm.
deft_code

4
Câu trả lời này hiện đã được hơn 2 năm nên có thể bị lỗi thời nếu bạn đang sử dụng phiên bản gdb mới hơn. Kể từ gdb 7.2, bây giờ bạn có thể sử dụng save breakpointslệnh.
aculich

11

Đặt các lệnh và điểm dừng GDB của bạn trong tệp .gdbinit giống như bạn có thể nhập chúng tại gdb>dấu nhắc và GDB sẽ tự động tải và chạy chúng khi khởi động. Đây là một tệp trên mỗi thư mục, vì vậy bạn có thể có các tệp khác nhau cho các dự án khác nhau.


1
Điều này thực sự không hoạt động, tôi nhận được "cảnh báo: save-tracepoints: không có tracepoints để lưu. ' Điều này mặc dù các điểm dừng được đặt. Sử dụng gdb 6.8.
Trình mã hóa

Điều này làm việc cho tôi. GDB cần sự hiện diện của .gdbinit toàn cầu trong $ HOME / .gdbinit của bạn với nội dung 'add-auto-load-safe-path /home/johnny/src/.gdbinit' và do đó, thư mục src /
Truthadjustr

9

Một phần mở rộng cho phần mở rộng của anon cho câu trả lời của Julian :

.gdbinit:

define bsave
    shell rm -f brestore.txt
    set logging file brestore.txt
    set logging on
    info break
    set logging off
    # Reformat on-the-fly to a valid GDB command file
    shell perl -n -e 'print "break $1\n" if /^\d+.+?(\S+)$/g' brestore.txt > brestore.gdb
end
document bsave
  store actual breakpoints
end

define brestore
  source brestore.gdb
end
document brestore
  restore breakpoints saved by bsave
end

Với brestorebạn sau đó có thể khôi phục các điểm dừng được lưu với bsave.


Đây là một regex tốt hơn: perl -ne "print \" break \ $ 1 \ n \ "if /at\s(.*:\d+)/" brestore.txt
George Godik

6

Mở rộng cho câu trả lời từ Johannes : bạn có thể tự động định dạng lại đầu ra info breakthành tệp lệnh GDB hợp lệ:

.gdbinit:

define bsave
   shell rm -f brestore.txt
   set logging file brestore.txt
   set logging on
   info break
   set logging off
   # Reformat on-the-fly to a valid gdb command file
   shell perl -n -e 'print "break $1\n" if /^\d+.+?(\S+)$/g' brestore.txt > brestore.gdb
end
document bsave
  store actual breakpoints
end

Sau đó, bạn có một lệnh lệnh hợp lệ trong brestore.gdb .

Điều này làm việc cho tôi khi ứng dụng được biên dịch với -g .

Tôi cũng đã thử nghiệm thành công với GDB v6.8 trên Ubuntu 9.10 (Karmic Koala).


1
Cảm ơn bạn cho đoạn trích này! Công trình tuyệt vời. Đã thử nghiệm thành công với GNU gdb 6.3.50-20050815 (phiên bản Apple gdb-966) trong CarbonEmacs GNU Emacs 22.3.1 (i386-apple-darwin9.6.0, Phiên bản Carbon 1.6.0) trên Mac OS 10.5.8.
Pestophagous


3

Đặt phần sau vào ~ / .gdbinit để xác định bsavebrestore là các lệnh GDB để lưu và khôi phục các điểm dừng.

define bsave
    save breakpoints ~/.breakpoints
end

define brestore
   source ~/.breakpoints
end

1

cảnh báo: Giao thức đầu ra hiện tại không hỗ trợ chuyển hướng

Tôi cũng nhận được lỗi / cảnh báo này trong GDB khi thử bật đăng nhập ở chế độ TUI . Tuy nhiên, việc ghi nhật ký dường như hoạt động khi ở chế độ "không TUI". Vì vậy, tôi rời khỏi chế độ TUI bất cứ khi nào tôi muốn đăng nhập một cái gì đó. (Chuyển đổi qua lại vào chế độ TUI với Ctrl+X , Ctrl+A ).

Đây là cách tôi làm việc:

  1. bắt đầu GDB (ở chế độ bình thường)
  2. cho phép đăng nhập: set logging on - bây giờ nó không nên phàn nàn.
  3. chuyển đổi qua lại chế độ TUI và thực hiện công cụ GDB
  4. Bất cứ khi nào tôi muốn đăng nhập một cái gì đó (như một bãi chứa backtrace lớn) - chuyển sang chế độ bình thường

Ồ, và nếu bạn thích sử dụng "màn hình" (như tôi làm) thì sẽ hơi lộn xộn, vì nó sử dụng cùng các phím nóng.
Magnux

1

Tôi thấy phần bổ sung sau đây cho câu trả lời trước hữu ích để lưu / tải các điểm dừng vào một tệp cụ thể.

  • Lưu điểm dừng: bsave {tên tệp}
  • Tải điểm dừng: bload {tên tệp}

Như trong câu trả lời trước, thêm mã sau vào tệp ~ / .gdbinit

# Save breakpoints to a file
define bsave
    if $argc != 1
        help bsave
    else
    save breakpoints $arg0
    end
end
document bsave
Saves all current defined breakpoints to the defined file in the PWD
Usage: bsave <filename>
end

# Loads breakpoints from a file
define bload
    if $argc != 1
        help bload
    else
        source $arg0
    end
end
document bload
Loads all breakpoints from the defined file in the PWD
Usage: bload <filename>
end

0

Vấn đề là việc thiết lập một điểm dừng là nhạy cảm bối cảnh. Điều gì nếu bạn có hai hàm tĩnh có tên foo thì sao?

Nếu bạn đã gỡ lỗi một trong các mô-đun xác định foo, thì GDB sẽ cho rằng bạn có nghĩa là mô-đun đó. Nhưng nếu bạn chỉ cần đổ "phá vỡ foo" vào một tập tin và sau đó đọc rằng tập tin lúc khởi động, nó sẽ không được rõ ràng mà chức năng foo bạn có ý nghĩa.


0

Còn ý tưởng nào khác không? tôi có

warning: Current output protocol does not support redirection

sau

set logging on

BIÊN TẬP:

Tôi biết câu hỏi đó là "làm thế nào để lưu danh sách các điểm dừng", tuy nhiên tôi mới phát hiện ra rằng với GDB, chúng ta có thể chỉ cần đặt các điểm dừng "được lưu trong tệp"

gdb> source breakpoints.txt

nơi breakpoints.txtlà một tập tin như thế này:

break main.cpp:25
break engine.cpp:465
break wheel.cpp:57
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.