Đặt điểm ngắt trong mã C hoặc C ++ theo lập trình cho gdb trên Linux


104

Làm cách nào để đặt một điểm ngắt trong mã C hoặc C ++ theo chương trình sẽ hoạt động cho gdb trên Linux?

I E:

int main(int argc, char** argv)
{
    /* set breakpoint here! */
    int a = 3;
    a++;  /*  In gdb> print a;  expect result to be 3 */
    return 0;
}

8
Rất nhiều lưu ý phụ (xin lỗi nitpick), nhưng nếu bạn lo lắng về tính di động thì có lẽ bạn cũng lo lắng về tính đúng đắn - do đó int mainthay vì vậy void main.
Stuart Golodetz

@Stuart - Đã sửa. Nên đã làm điều đó một thời gian trước đây.
J. Polfer

4
@ J.Polfer: Tuy nhiên, điều return 0này là không cần thiết, và chỉ là tiếng ồn!
Các cuộc đua ánh sáng trong quỹ đạo vào

Câu trả lời:


106

Một cách là báo hiệu ngắt:

#include <csignal>

// Generate an interrupt
std::raise(SIGINT);

Trong C:

#include <signal.h>
raise(SIGINT);

CẬP NHẬT : MSDN nói rằng Windows không thực sự hỗ trợ SIGINT, vì vậy nếu tính di động là mối quan tâm, có lẽ bạn nên sử dụng SIGABRT.


Có, điều này sẽ hoạt động trên các hệ điều hành / trình biên dịch / trình gỡ lỗi.
Håvard S

1
Tôi không biết các trình gỡ lỗi khác, nhưng gdb khá linh hoạt trong việc xử lý tín hiệu .
Cascabel

4
Chúng tôi tìm thấy SIGTRAP tốt hơn trên một số unices
JBRWilkinson

1
trong Windows, MSVC, bạn có thể sử dụng __debug_break, DebugBreak hoặc _asm {int 3}.
Fernando Gonzalez Sanchez

2
@FernandoGonzalezSanchez: thực ra tên hàm là __debugbreak()KHÔNG __debug_break() , như bạn có thể thấy ở đây
Morix Dev

27

Trong một dự án mà tôi đang thực hiện, chúng tôi thực hiện điều này:

raise(SIGABRT);  /* To continue from here in GDB: "signal 0". */

(Trong trường hợp của chúng tôi, chúng tôi muốn gặp sự cố nếu điều này xảy ra bên ngoài trình gỡ lỗi, tạo báo cáo sự cố nếu có thể. Đó là một lý do chúng tôi sử dụng SIGABRT. Việc này có thể di chuyển được trên Windows, Mac và Linux phải mất vài lần. Chúng tôi đã kết thúc với một vài #ifdefs, đã nhận xét hữu ích tại đây: http://hg.mozilla.org/mozilla-central/file/98fa9c0cff7a/js/src/jsutil.cpp#l66 .)


2
Như cửa sổ thông thường không giống như những người khác :)
mathk

Có thể đưa ra "tín hiệu 0" để tiếp tục chương trình chương trình ở trạng thái tạm dừng? Sẽ rất tuyệt nếu có thể sử dụng 'n' hoặc 's' từ thời điểm này, mà không cần cấp 'c'.
Jason Doucette

2
@JasonDoucette Nếu bạn thực sự chỉ muốn chương trình tạm dừng, bạn có thể muốn thêm một breakpoint()hàm vào chương trình của mình (nó có thể trống hoặc chỉ chứa một câu lệnh in) và thêm break breakpointvào của bạn ~/.gdbinit.
Jason Orendorff

26

Bằng cách nhìn vào đây , tôi đã tìm thấy cách sau:

void main(int argc, char** argv)
{
    asm("int $3");
    int a = 3;
    a++;  //  In gdb> print a;  expect result to be 3
}

Điều này có vẻ là một hackish liên lạc với tôi. Và tôi nghĩ điều này chỉ hoạt động trên kiến ​​trúc x86.


3
Và chỉ với các trình biên dịch hỗ trợ cú pháp hợp ngữ AT&T. Đặc biệt, trình biên dịch ( cl.exe) của Microsoft không hỗ trợ cú pháp này mà sử dụng một cú pháp khác.
Håvard S

câu hỏi là về linux, vì vậy tôi đoán chúng ta có thể giả định rằng cú pháp gcc sẽ hoạt động cho x86.
js.

BTW - Tôi đã thử cách trên trên máy x86 của mình và nó đã hoạt động. Tôi tò mò nếu có cách nào tốt hơn để làm điều đó. Hình như có.
J. Polfer

2
Tôi đang sử dụng mingw trên windows nên các đề xuất khác không thể giúp tôi. Việc nâng tín hiệu SIGINT chỉ kết thúc ứng dụng, SIGTRAP không được xác định trong tiêu đề mingw ... Sử dụng lệnh int thực sự gửi SIGTRAP và gdb ngắt một cách độc đáo trên dòng thích hợp.
Machta

Trong Linux, int 3tăng một SIGTRAP.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

11

__asm__("int $3"); nên làm việc:

int main(int argc, char** argv)
{
    /* set breakpoint here! */
    int a = 3;
    __asm__("int $3");
    a++;  /*  In gdb> print a;  expect result to be 3 */
    return 0;
}

1
Tôi thích #defineđiều này, vì vậy tôi không có tôi nhớ cú pháp. Tôi đã rắc nó xuyên suốt mã của mình, đôi khi thay assert()vì dừng trình debiugger, hãy để tôi kiểm tra tất cả các biến & ngăn xếp. Và, tất nhiên, như khẳng định, tôi không cần phải gỡ bỏ nó cho mã sản xuất
Mawg nói Khôi phục Monica

Điều thú vị là điều này có 10 phiếu ủng hộ khi các ràng buộc câu hỏi của "Linux" và "GDB" đưa ra nhiều tùy chọn ngoài việc sử dụng đến lắp ráp, điều này luôn phải là phương sách cuối cùng vì lợi ích của tính di động nếu không có gì khác. Hãy xem một số câu trả lời khác.
Benjamin Crawford Ctrl-Alt-Tut

5

Thất vọng khi thấy rất nhiều câu trả lời không sử dụng tín hiệu dành riêng cho breakpoint phần mềm, SIGTRAP:

#include <signal.h>

raise(SIGTRAP); // At the location of the BP.

1

Trên OS X, bạn chỉ có thể gọi std::abort()(nó có thể tương tự trên Linux)


Thư viện nào?
Alex

Đây là một phần của thư viện C ++ tiêu chuẩn và là nền tảng đa nền tảng, nơi các trình biên dịch tuân thủ C ++ 11 tồn tại. Tuy nhiên, điều này làm tăng SIGABRT, đây không thực sự là một tín hiệu thích hợp để tăng trong trường hợp này.
Benjamin Crawford Ctrl-Alt-Tut
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.