Linux의 gdb에 대해 프로그래밍 방식으로 C 또는 C ++ 코드에 중단 점 설정


105

Linux의 gdb에서 작동하는 프로그래밍 방식으로 C 또는 C ++ 코드에서 중단 점을 어떻게 설정할 수 있습니까?

즉 :

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
아주 많은 부수적 인 부분이지만 (미안하지만, 이식성에 대해 걱정한다면 아마도 정확성에 대해서도 걱정할 int mainvoid main입니다. 따라서 .
Stuart Golodetz

@Stuart-수정 됨. 얼마 전에 그랬어 야 했어.
J. Polfer 2011 년

4
@J. Polfer : return 0그래도 필요하지 않고 그냥 소음입니다!
궤도의 가벼운 경주

답변:


107

한 가지 방법은 인터럽트 신호를 보내는 것입니다.

#include <csignal>

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

C에서 :

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

업데이트 : MSDN 은 Windows가 실제로 지원하지 않는다고 명시 하고 SIGINT있으므로 이식성이 우려된다면 SIGABRT.


예, 이것은 운영 체제 / 컴파일러 / 디버거에서 작동합니다.
Håvard S

1
다른 디버거는 모르지만 gdb는 신호 처리 에 대해 매우 유연 합니다.
Cascabel

4
우리는 약간의 유닉스에 더 나은 SIGTRAP을 발견
JBRWilkinson

1
Windows, MSVC에서는 __debug_break, DebugBreak 또는 _asm {int 3}를 사용할 수 있습니다.
Fernando Gonzalez Sanchez

2
@FernandoGonzalezSanchez : 실제로 함수 이름은 __debugbreak()이고 NOT입니다 __debug_break() . 여기에서
Morix Dev

27

내가 작업하는 프로젝트에서 다음을 수행합니다.

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

(이 경우 디버거 외부에서 발생하면 크래시가 발생하여 가능한 경우 크래시 보고서를 생성하고 싶었습니다. 이것이 우리가 SIGABRT를 사용한 이유 중 하나입니다. Windows, Mac 및 Linux에서 이식 가능하게이 작업을 수행하려면 여러 번 시도해야했습니다. 결국 몇 번의 시도로 끝났습니다. #ifdefs, 여기에 유용하게 댓글 달기 : http://hg.mozilla.org/mozilla-central/file/98fa9c0cff7a/js/src/jsutil.cpp#l66 .)


2
평소처럼 창은 다른 창처럼 보이지 않습니다 :)
mathk

일시 정지 된 상태에서 프로그램을 계속하기 위해 "신호 0"을 발행 할 수 있습니까? 이 시점에서 'c'를 발행하지 않고 'n'또는 's'를 사용할 수 있으면 좋을 것입니다.
Jason Doucette 2016 년

2
당신은 정말 그냥 일시 중지하려면 프로그램을 원하는 경우 @JasonDoucette, 당신은 추가 할 수 있습니다 breakpoint()(이 비어 있거나 그냥 인쇄 문을 포함 할 수 있습니다) 프로그램에서 기능을 추가합니다 break breakpoint당신에게 ~/.gdbinit.
Jason Orendorff

26

여기 를 보면 다음과 같은 방법을 찾았습니다.

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

이것은 나에게 터치 hackish처럼 보입니다. 그리고 이것은 x86 아키텍처에서만 작동한다고 생각합니다.


3
그리고 AT & T 어셈블리 구문을 지원하는 컴파일러에서만 가능합니다. 특히 Microsoft의 컴파일러 ( cl.exe)는이 구문을 지원하지 않지만 다른 구문을 사용합니다.
Håvard S

질문은 리눅스에 관한 것이기 때문에 gcc 구문이 x86에서 작동한다고 가정 할 수 있습니다.
js.

BTW-x86 컴퓨터에서 위의 작업을 시도했지만 작동했습니다. 더 나은 방법이 있는지 궁금했습니다. 있는 것 같습니다.
J. Polfer 2010

2
다른 제안이 나를 도울 수 없도록 Windows에서 mingw를 사용하고 있습니다. SIGINT 신호를 올리면 응용 프로그램이 종료되고 SIGTRAP는 mingw 헤더에 정의되어 있지 않습니다. int 명령어를 사용하면 실제로 SIGTRAP를 보내고 gdb는 적절한 줄에서 잘 나갑니다.
Machta 2014 년

Linux에서 int 3SIGTRAP을 발생시킵니다.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

12

__asm__("int $3"); 작동해야합니다.

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
나는 이것을 좋아 #define하므로 구문을 기억할 필요가 없습니다. 나는 때때로 대신에, 내 코드를 통해 뿌려가 assert()debiugger의하자를 정지하는 날 모든 변수 및 스택을 검사이기 때문에. 그리고, 물론, 어설처럼, 내가 생산 코드를 제거 할 필요는 없습니다
Mawg는 분석 재개 모니카 말한다

흥미롭게도 "Linux"와 "GDB"의 질문 제약이 어셈블리에 의존하지 않고 많은 옵션을 제공 할 때 10 개의 업 보트가 있다는 점이 흥미 롭습니다. 이것은 항상 이식성을위한 최후의 수단이어야합니다. 다른 답변을 참조하십시오.
Benjamin Crawford Ctrl-Alt-Tut

5

소프트웨어 중단 점에 대한 전용 신호를 사용하지 않고 너무 많은 답변을 보는 것이 실망 스럽습니다 SIGTRAP.

#include <signal.h>

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

1

OS X에서는 호출 만 할 수 있습니다 std::abort()(Linux에서도 동일 할 수 있음).


어느 도서관?
Alex

이것은 표준 C ++ 라이브러리의 일부이며 C ++ 11 호환 컴파일러가있는 교차 플랫폼입니다. 그러나 이것은 SIGABRT를 발생시킵니다. 이것은이 경우에 발생하기에 적절한 신호가 아닙니다.
Benjamin Crawford Ctrl-Alt-Tut
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.