2009-07-12 27 views
89

Tôi đang làm việc trên ứng dụng đa luồng và tôi muốn gỡ lỗi ứng dụng bằng GDB.Chạy ứng dụng trong GDB Cho đến khi ngoại lệ xảy ra

Vấn đề là, một trong những chủ đề của tôi giữ chết với thông điệp:

pure virtual method called 
terminate called without an active exception 
Abort 

tôi biết nguyên nhân của thông báo đó, nhưng tôi không có ý tưởng nơi trong chủ đề của tôi nó xảy ra. Một backtrace thực sự sẽ hữu ích.

Khi tôi chạy ứng dụng của mình trong GDB, nó tạm dừng mỗi lần một chuỗi bị tạm ngưng hoặc tiếp tục. Tôi muốn ứng dụng của tôi tiếp tục chạy bình thường cho đến khi một trong các chủ đề chết với ngoại lệ đó, tại thời điểm đó mọi thứ sẽ dừng lại để tôi có thể có được một backtrace.

+0

Báo cáo GDB báo cáo khi nào nó tạm dừng? bạn sẽ có thể chạy một lệnh như 'xử lý SIGUSR1 vượt qua noprint nostop' – Hasturkun

Trả lời

126

Bạn có thể thử sử dụng một "catchpoint" (catch throw) để ngăn chặn các chương trình gỡ rối tại điểm mà các ngoại lệ được tạo ra.

Sau excerpt Từ hướng dẫn gdb mô tả tính năng điểm đánh dấu.


5.1.3 Thiết catchpoints

Bạn có thể sử dụng catchpoints để gây ra debugger dừng lại để một số loại sự kiện chương trình, chẳng hạn như trường hợp ngoại lệ C++ hoặc tải một thư viện chia sẻ. Sử dụng lệnh catch để thiết lập một điểm bắt.

  • bắt kiện

    ngừng hoạt động khi kiện xảy ra. sự kiện có thể là bất kỳ những điều sau đây:

    • ném

      Các ném một ngoại lệ ++ C.

    • bắt

      Khai thác thuỷ sản của một ++ ngoại lệ C.

    • exec

      Một cuộc gọi đến exec. Tính năng này hiện chỉ khả dụng cho HP-UX.

    • ngã ba

      Một cuộc gọi đến ngã ba. Tính năng này hiện chỉ khả dụng cho HP-UX.

    • vfork

      Một cuộc gọi đến vfork. Tính năng này hiện chỉ khả dụng cho HP-UX.

    • tải hoặc tải libname

      Các nạp năng động của bất kỳ thư viện chia sẻ, hoặc tải của libname thư viện. Tính năng này hiện chỉ khả dụng cho HP-UX.

    • dỡ bỏ hoặc dỡ bỏ libname

      Các dỡ của bất kỳ thư viện tự động nạp chia sẻ, hoặc dỡ hàng của libname thư viện. Tính năng này hiện chỉ khả dụng cho HP-UX.

  • kiện tcatch

    Đặt một catchpoint được kích hoạt chỉ cho một cửa. Điểm bắt được tự động xóa sau lần đầu tiên sự kiện bị bắt.

Sử dụng lệnh info break vào danh sách các catchpoints hiện hành.

Hiện tại có một số hạn chế đối với C++ xử lý ngoại lệ (bắt ném và bắt catch) trong GDB:

* If you call a function interactively, GDB normally returns control to you when the function has finished executing. If the call raises an exception, however, the call may bypass the mechanism that returns control to you and cause your program either to abort or to simply continue running until it hits a breakpoint, catches a signal that GDB is listening for, or exits. This is the case even if you set a catchpoint for the exception; catchpoints on exceptions are disabled within interactive calls. 

* You cannot raise an exception interactively. 

* You cannot install an exception handler interactively. 

Đôi khi bắt không phải là cách tốt nhất để xử lý debug ngoại lệ: nếu bạn cần phải biết chính xác nơi một ngoại lệ được nâng lên, tốt hơn là dừng trước khi xử lý ngoại lệ được gọi, vì cách đó bạn có thể thấy ngăn xếp trước khi bất kỳ sự cố gắng nào xảy ra. Nếu bạn đặt một điểm ngắt trong một trình xử lý ngoại lệ thay vào đó, nó có thể không dễ dàng để tìm ra nơi ngoại lệ được nâng lên.

Để dừng ngay trước khi xử lý ngoại lệ được gọi, bạn cần một số kiến ​​thức về việc triển khai. Trong trường hợp của GNU C++, trường hợp ngoại lệ được nâng lên bằng cách gọi một hàm thư viện mang tên __raise_exception trong đó có giao diện ANSI C sau:

/* addr is where the exception identifier is stored. 
    id is the exception identifier. */ 
void __raise_exception (void **addr, void *id); 

Để thực hiện bắt debugger tất cả các trường hợp ngoại lệ trước khi bất kỳ stack ươm diễn ra, đặt một breakpoint trên __raise_exception (xem phần Điểm dừng; điểm quan sát và ngoại lệ).

Với điểm ngắt có điều kiện (xem phần Điều kiện ngắt) phụ thuộc vào giá trị của id, bạn có thể dừng chương trình của mình khi ngoại lệ cụ thể được nâng lên. Bạn có thể sử dụng nhiều điểm ngắt có điều kiện để dừng chương trình của bạn khi bất kỳ một số ngoại lệ nào được nâng lên.

+0

Xin vui lòng có upvote thứ 100. – YSC

5

Set một breakpoint trên __pure_virtual

+0

Trong câu trả lời @JeffreyHill, nó được gọi là __cxa_pure_virtual ngay bây giờ. Tôi không biết cách kiểm tra bản thân mình, vì vậy tôi không muốn chỉnh sửa câu trả lời. Tôi không có ý định bỏ phiếu xuống, nhưng câu trả lời có thể sai ngay bây giờ và nên được chỉnh sửa bởi một người biết điều gì là chính xác. –

3

FWIW, rõ ràng, trong gcc 4.1, tên hàm thích hợp đã thay đổi và người ta phải đặt điểm ngắt trong hàm này.

__cxa_pure_virtual

Các vấn đề liên quan