OS/X에서 C ++ 백 트레이스 생성 (10.5.7)
-
16-09-2019 - |
문제
나는 백트레이스와 백트레이스 _symbols를 사용하여 로깅/진단을 목적으로 프로그래밍 방식 스택 추적을 생성했습니다. 그러나 대략적으로 작동하는 것 같습니다. 저는 약간의 멍청이가 생기고 있으며 각 기능 호출과 관련된 파일/줄 번호가 없습니다 (GDB BT 호출 또는 무언가 내에서 기대할 수 있듯이). 예는 다음과 같습니다.
1 Leonardo 0x00006989 _ZN9ExceptionC2E13ExceptionType + 111
2 Leonardo 0x00006a20 _ZN9ExceptionC1E13ExceptionType + 24
3 LEONARDO 0x0000AB64 _ZN5RULES11APPLYACTIONER16APPLICABLEACTIONR9GAMESTATE + 1060
4 Leonardo 0x0000ed15 _ZN9Simulator8simateev + 2179
5 Leonardo 0x0000eec9 _ZN9Simulator8simulateei + 37
6 Leonardo 0x00009729 Main + 45
7 Leonardo 0x000025c6 시작 + 54
내가 놓친 것이 무엇이든, 어리석은 일을하고 있습니까?
다른 일부 tidbits :
rdynamic
G ++ 버전 (4.0.1)의 링크 옵션을 사용하고 있습니다.-g/-g3
아무런 차이가 없습니다.abi::__cxa__demangle
아무것도하지 않는 것 같습니다
해결책
뒤쪽은 일반적으로 다음 형식으로 Backtrace_symbols에서 돌아온다.
./myapp(_zn4test3fooev+0x8) [0x821c874
abi :: __ cxa_demangle은 함수 이름 만 기대합니다. 따라서 일부 구문 분석은 먼저 흔적에서 수행되어야합니다.
std::string trace(backtrace[idx]);
// attempt to demangle
{
std::string::size_type begin, end;
// find the beginning and the end of the useful part of the trace
begin = trace.find_first_of('(') + 1;
end = trace.find_last_of('+');
// if they were found, we'll go ahead and demangle
if (begin != std::string::npos && end != std::string::npos) {
trace = trace.substr(begin, end - begin);
size_t maxName = 1024;
int demangleStatus;
char* demangledName = (char*) malloc(maxName);
if ((demangledName = abi::__cxa_demangle(trace.c_str(), demangledName, &maxName,
&demangleStatus)) && demangleStatus == 0) {
trace = demangledName; // the demangled name is now in our trace string
}
free(demangledName);
}
}
나는 이것을 내 자신의 프로젝트에서 테스트했으며 다음 형식으로 다소 더 좋은 뒤쪽을 제공합니다.
테스트 :: foo ()
물론, 줄 번호는 없지만 가능하지는 않습니다.
다른 팁
나는 어떤 구현도 모른다 backtrace_symbols()
기호+오프셋 이상을 제공합니다.
에 관해서 abi:: __cxa__demangle
, 당신은 당신이 당신이 + line
접미사, 그렇지 않으면 기호를 유효한 것으로 인식하지 않습니다.