2010-12-01 5 views
80

Linux에서 gdb로 사용할 수있는 C 또는 C++ 코드에서 프로그래밍 방식으로 중단 점을 설정할 수 있습니까?리눅스에서 gdb에 대한 C 또는 C++ 코드의 중단 점 설정 프로그래밍: 1283 :

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

이 나에게 hackish 터치를 보인다

즉 :

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

부탁합니다. (미안하지만) 휴대성에 대해 걱정한다면 매우 걱정할 것입니다. 정확성 - 그러므로'main main'보다는'int main'을 사용하십시오. –

+0

@Stuart - 고정됨. 오래전에 그렇게 했어야 했어. –

+3

@ J.Polfer :'return 0'은 필요하지 않습니다. –

답변

77

한 가지 방법은 인터럽트 신호에 의해 MSDN states Windows가 정말 SIGINT를 지원하지 않는 휴대 성이 문제가되는 경우 그래서, SIGABRT을 사용하는 것이 좋습니다. .이 충돌 보고서 가능한 경우를 생성, 디버거 밖에서 일어난 경우

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

(우리의 경우 우리가 열심히 충돌 싶어 그게 우리가 사용하는 이유 중 하나입니다 : I가 작업 프로젝트에서

+0

이것은 더 휴대 가능합니다. 맞습니까? –

+0

예, 운영 체제/컴파일러/디버거에서 작동합니다. –

+1

다른 디버거는 모르지만 gdb는 [신호 처리] (http://www.delorie.com/gnu/docs/gdb/gdb_39.html)에 대해 매우 유연합니다. – Cascabel

18

here을보고함으로써, 나는 다음과 같은 방법을 발견했다. 그리고 이것은 x86 아키텍처에서만 작동한다고 생각합니다. C에서

#include <csignal> 

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

:

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

UPDATE :

+3

AT & T 어셈블리 구문을 지원하는 컴파일러 만 사용해야합니다. 특히 Microsoft의 컴파일러 ('cl.exe')는이 구문을 지원하지 않지만 다른 구문을 사용합니다. –

+0

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

+0

BTW - 위의 코드를 x86 시스템에서 사용했지만 제대로 작동했습니다. 더 나은 방법이 있다면 궁금했습니다. 거기있는 것처럼 보입니다. –

25

, 우리는 이렇게 ... SIGABRT가 이식 윈도우, 맥을 통해 이렇게, 리눅스는 여러 가지 시도를했다 우리는 몇 위해서 #ifdefs, 유용하게 여기 주석으로 돌아가 셨습니다 : http://hg.mozilla.org/mozilla-central/file/98fa9c0cff7a/js/src/jsutil.cpp#l66)

+2

보통 창은 다른 것처럼 보이지 않습니다. – mathk

+0

"신호 0"을 발행하여 일시 중지 상태에서 프로그램을 계속 프로그래밍 할 수 있습니까? 이 시점에서 'n'또는 's'를 사용할 수 있다면 'c'가 발행되지 않아도 좋을 것입니다. –

+1

@JasonDoucette 만약 당신이 정말로 프로그램을 멈추고 싶다면, 프로그램에'breakpoint()'함수를 추가하고 싶을 것입니다. (비어 있거나 그냥 print 문을 포함 할 수 있습니다)'break breakpoint'를'~/.gdbinit'. –

9

__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; 
} 
,
+0

굉장합니다, 고마워요! – leishman

+1

나는 이것을 #define으로 정의하고 싶다. 그래서 구문을 기억할 필요가 없다. 나는 debiugger를 멈추었으므로 모든 변수와 스택을 검사 해 보도록하겠다. 때때로 assert() 대신에 내 코드에 걸쳐 뿌렸다. 그리고 물론, assert와 마찬가지로 프로덕션 코드로 제거 할 필요가 없습니다. – Mawg

1

OSX에서는 std::abort() (리눅스에서 동일 할 수도 있음)을

+0

어떤 라이브러리입니까? – Alex