디버그 브레이크 ()/__ 디버그 브레이크와 동등한 휴대용이 있습니까?
-
05-07-2019 - |
문제
MSVC에서 디버그 브레이크 () 또는 __debugbreak 디버거가 파손됩니다. x86에서는 "_asm int 3"을 작성하는 것과 같습니다. x64에서는 다른 것입니다. GCC (또는 기타 표준 컴파일러)로 컴파일 할 때도 디버거를 중단하고 싶습니다. 플랫폼 독립적 인 기능이나 고유 한 것이 있습니까? 나는 봤다 xcode 질문 그것에 대해, 그러나 그것은 충분히 휴대 할 수없는 것처럼 보이지 않습니다.
Sidenote : 주로 Assert를 구현하고 싶고 Assert ()를 사용할 수 있다는 것을 이해하지만 Debug_break 또는 무언가를 코드에 작성하고 싶습니다.
해결책
현재 아키텍처 또는 플랫폼을 기반으로 다른 구성으로 확장되는 #ifdef를 기반으로 조건부 매크로를 정의하는 것은 어떻습니까?
같은 것 :
#ifdef _MSC_VER
#define DEBUG_BREAK __debugbreak()
#else
...
#endif
이는 사전 처리기에 의해 코드가 컴파일되는 플랫폼을 기반으로 올바른 디버거 브레이크 명령어를 확장합니다. 이렇게하면 항상 사용합니다 DEBUG_BREAK
코드에서.
다른 팁
대부분의 POSIX 시스템에 휴대 할 수있는 방법은 다음과 같습니다.
raise(SIGTRAP);
GCC에는 이름이 내장 된 기능이 있습니다 __builtin_trap
당신이 볼 수있는 것 여기, 그러나 코드 실행에 도달하면 중단 된 것으로 가정합니다.
너 ~해야 한다 확인하십시오 __builtin_trap()
통화는 조건부이므로 코드는 이후에 방출되지 않습니다.
이 게시물은 5 분의 테스트, ymmv에 의해 촉진되었습니다.
이것은 적절한 COMPAT 라이브러리처럼 보입니다 https://github.com/scottt/debugbreak
방금 추가했습니다 모듈 에게 휴대용 스냅 킷 이를 위해 (휴대용 코드의 공개 도메인 스 니펫 모음). 휴대용 100%는 아니지만 매우 강력해야합니다.
__builtin_debugtrap
일부 버전의 Clang의 경우 (식별__has_builtin(__builtin_debugtrap)
)- MSVC 및 Intel C/C ++ 컴파일러 :
__debugbreak
- ARM C/C ++ 컴파일러의 경우 :
__breakpoint(42)
- x86/x86_64의 경우 어셈블리 :
int $03
- 팔 엄지 손가락, 조립 :
.inst 0xde01
- Arm Aarch64의 경우 어셈블리 :
.inst 0xd4200000
- 다른 팔의 경우 조립 :
.inst 0xe7f001f0
- 알파, 조립 :
bpt
- GCC가있는 호스트 C (또는 그로 인해 가장 무서운 것)의 경우,
__builtin_trap
- 그렇지 않으면 포함하십시오
signal.h
그리고- 만약에
defined(SIGTRAP)
(예 : Posix),raise(SIGTRAP)
- 그렇지 않으면,
raise(SIGABRT)
- 만약에
앞으로 휴대용 스냅 펫의 모듈은 다른 논리를 포함하도록 확장 될 수 있으며이 답변을 업데이트하는 것을 잊어 버리므로 업데이트를 찾아야합니다. 공개 도메인 (CC0)이므로 코드를 훔치십시오.
Assert (x) 휴대용으로 충분히 고려하면 Assert (False)는 문제에 대한 명백한 휴대용 솔루션 인 것 같습니다.
충돌 관련 조건을 디버깅하려는 경우 구식 Abort ()가 대부분의 플랫폼에서 통화 스택을 제공합니다. 단점은 현재 PC에서 계속할 수 없다는 것입니다.
'정상'디버그 브레이크를 사용하는 대신 0으로 나누기와 같이 다음 중 하나를 사용하지 않는 이유는 무엇입니까?
int iCrash = 13 / 0;
또는 널 포인터를 불러 일으킨다 :
BYTE bCrash = *(BYTE *)(NULL);
적어도 이것은 많은 플랫폼/아키텍처를 휴대용으로 허용합니다.
많은 디버거에서 당신은 어떤 예외에 대해 어떤 행동을 수행 할 것인지를 지정하여 위의 중 하나가 발생할 때 (일시 정지 실행, ALA ALA "int 3"명령어)에 따라 행동 할 수 있으며 예외가 생성 될 수 있습니다.
#define __debugbreak() \
do \
{ static bool b; \
while (!b) \
sleep(1); \
b = false; \
} while (false)
프로세스가자는 경우 디버거를 프로세스에 부착하고 변수 B를 변경하여 루프를 깨고 작업을 수행 할 수 있습니다. 이 코드는 최적화 된 빌드에서 작동하지 않을 수 있습니다!