2016-03-04 44 views
0

我逼崩溃在OSX我wxWidgets的应用程序(MyApp),通过执​​行以下操作在事件处理程序:回溯没有给我完整的堆栈跟踪

void MainFrame::buggyFunc(wxCommandEvent &event) { 
    int* a = NULL; 
    *a = 1; 

这将生成以下堆栈跟踪:

0 MyApp       0x000000010dc5d5d5 generateCrashLog(int)     + 325 
1 MyApp       0x000000010dc5db46 abortHandler(int)      + 118 
2 libsystem_platform.dylib  0x00007fff94e6ceaa _sigtramp       () + 26 
3 ???        0x00000000ffffffff 0x0 + 4294967295 
4 MyApp       0x0000000108a5880b wxAppConsoleBase::HandleEvent(wxEvtHandler*, void (wxEvtHandler::*)(wxEvent&), wxEvent&) const + 139 
5 MyApp       0x0000000108a588b7 wxAppConsoleBase::CallEventHandler(wxEvtHandler*, wxEventFunctor&, wxEvent&) const + 151 
6 MyApp       0x0000000108ba96e7 wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&) + 231 
7 MyApp       0x0000000108ba94c3 wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*) + 243 
8 MyApp       0x0000000108bab276 wxEvtHandler::TryHereOnly(wxEvent&)  + 134 
9 MyApp       0x0000000108bac71d wxEvtHandler::TryBeforeAndHere(wxEvent&) + 77 
10 MyApp       0x0000000108bab03f wxEvtHandler::ProcessEventLocally(wxEvent&) + 47 
11 MyApp       0x0000000108baafb0 wxEvtHandler::ProcessEvent(wxEvent&)  + 336 
12 MyApp       0x0000000108a270df wxWindowBase::TryAfter(wxEvent&)   + 175 
13 MyApp       0x0000000108baafe6 wxEvtHandler::ProcessEvent(wxEvent&)  + 390 
14 MyApp       0x0000000108bab4a0 wxEvtHandler::SafelyProcessEvent(wxEvent&) + 32 
15 MyApp       0x0000000108a1e4e5 wxWindowBase::HandleWindowEvent(wxEvent&) const + 37 
16 MyApp       0x00000001089c8d8b wxMenuBase::SendEvent(int, int)   + 443 
17 MyApp       0x000000010885630a wxMenu::HandleCommandProcess(wxMenuItem*, wxWindow*) + 314 
18 MyApp       0x00000001088d8b6b -[wxNSMenuItem clickedAction:] + 107 
19 libsystem_trace.dylib   0x00007fff9052107a _os_activity_initiate 

and so on... 

问题1: 为什么不在堆栈跟踪buggyFunc?如果我使用backtrace,libunwindwxDebugReport/wxStackWalker(如VZ所建议),则无关紧要。结果堆栈跟踪总是相同的。最顶级的功能从来不在列表中。现在,如果buggyFunc要调用另一个函数(假设为buggyFunc2),那么在崩溃被强制的情况下,buggyFunc实际上将包含在内,而buggyFunc2则不会。那么为什么最顶级的功能不会出现在跟踪中?

问题2:(解决见回答以下) 当我运行在调试模式下MyApp,它说Caught signal 11,这是一个SIGSEGV,这是我所期待的,但释放模式使4,这是SIGILL。这里发生了什么事?

答:多亏了VZ的建议,我看着在Xcode的构建设置,发现这个:

enter image description here 设置Optimization levelNone解决了这个问题。不过,现在我已经得到了另一个问题...

问题3: 当我建立一个RelWithDebInfo版本的应用程序,我仍然可以在堆栈跟踪有意义的函数名,尽管Generate Debug Symbols设置为No它。为什么是这样?

回答

1

我不能直接回答你的第一个问题,但是如果你使用wxWidgets无论如何,你为什么不使用wxStackWalker甚至wxDebugReport而不是重新实现它们?至于第二个,你真的需要看反汇编,很可能是优化器用完全不同的东西替换你的代码,甚至完全删除它,因为它似乎没有任何副作用。

编辑:至于第三个问题(应该单独提出这个问题,因为它与其他问题没有多大关系),即使没有调试信息,函数名仍保留在生成的二进制文件中,您可以使用strip摆脱他们(虽然通常应该没有真正的理由)。

+0

谢谢你的建议。我尝试使用提供的示例实现'wxDebugReport',但我得到一个链接器错误。 '架构x86_64的未定义符号:“wxDebugReport :: AddAll(wxDebugReport :: Context)”'。似乎无法找到关于此的任何信息。未定义通常意味着缺少一个对象(或框架),但我认为这个类只是wxWidgets的一部分。 – Ash

+0

另外,我尝试使用wxStackWalker,但我遇到了与我的问题中所述相同的问题。 'buggyFunc'不在它走过的帧列表中。可能是因为wxStackWalker在内部使用了backtrace()。 – Ash

+0

'wxDebugReport'在“qa”库中,请确保与它链接。如果'wxStackWalker'不能正常工作,并且您可以通过一个简单示例重现它,请在[wxTrac](http://trac。wxwidgets.org/)。 –