обратная трассировка не дает мне полную трассировку стека

Я вызываю сбой в своем приложении wxWidgets (MyApp) в OSX, выполнив следующие действия в обработчике событий:

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, libunwind или wxDebugReport/wxStackWalker (как предлагает VZ). Результирующая трассировка стека всегда одинакова. Самая верхняя функция никогда не бывает в списке. Теперь, если buggyFunc будет вызывать другую функцию (скажем, buggyFunc2), где сбой принудительный, то buggyFunc будет фактически включен, а buggyFunc2 не будет. Так почему же самая верхняя функция никогда не присутствует в трассировке?

Вопрос 2: (РЕШЕНО. См. ответ ниже) Когда я запускаю MyApp в режиме отладки, он говорит Caught signal 11, то есть SIGSEGV, чего я и ожидал, но в режиме выпуска выдается 4, что равно SIGILL. Что тут происходит?

Ответ: Благодаря предложению VZ я просмотрел настройки сборки Xcode и нашел это:

введите здесь описание изображения Установка Optimization level на None решает эту проблему. Но теперь у меня другой вопрос...

Вопрос 3. Когда я создаю версию приложения RelWithDebInfo, я по-прежнему получаю осмысленные имена функций в трассировке стека, несмотря на то, что для нее Generate Debug Symbols установлено значение No. Почему это?


person Ash    schedule 04.03.2016    source источник


Ответы (1)


Я не могу напрямую ответить на ваш первый вопрос, но если вы все равно используете wxWidgets, почему бы вам не использовать wxStackWalker или даже wxDebugReport вместо того, чтобы переопределять их?

Что касается второго, вам действительно нужно посмотреть на дизассемблирование, вполне вероятно, что оптимизатор заменяет ваш код чем-то совершенно другим или даже полностью удаляет его, поскольку он не имеет никаких побочных эффектов.

Изменить: что касается третьего вопроса (который действительно следует задавать независимо, поскольку он не имеет большого отношения к другим), имена функций сохраняются в результирующем двоичном файле даже без отладочной информации, вы можете использовать strip, чтобы избавиться из них (хотя обычно для этого не должно быть реальной причины).

person VZ.    schedule 04.03.2016
comment
Спасибо за это предложение. Я попытался реализовать wxDebugReport, используя предоставленный пример, но получаю ошибку компоновщика. Undefined symbols for architecture x86_64: "wxDebugReport::AddAll(wxDebugReport::Context)". Кажется, не могу найти никакой информации об этом. Undefined обычно означает отсутствующий объект (или фреймворк), но я думал, что этот класс был просто частью wxWidgets. - person Ash; 06.03.2016
comment
Кроме того, я пытался использовать wxStackWalker, но у меня та же проблема, что и в моем вопросе. buggyFunc нет в списке пройденных им фреймов. Возможно, потому что wxStackWalker использует внутри себя backtrace(). - person Ash; 06.03.2016
comment
wxDebugReport находится в библиотеке qa, убедитесь, что вы связались с ним. Если wxStackWalker тоже не работает правильно, и если вы можете воспроизвести это на простом примере, откройте сообщение об ошибке на wxTrac об этом. - person VZ.; 06.03.2016
comment
Спасибо. Я нашел причину «вопроса 2» благодаря вашему предложению об оптимизаторе (см. отредактированный вопрос), но теперь у меня есть новый вопрос (вопрос 3). wxDebugReport работал у меня после ссылки на qa, хотя проблема с тем, что buggyFunc не включена в трассировку стека, все еще остается. Однако я заметил, что это самая верхняя функция, которая всегда исключается из трассировки (см. редактирование для вопроса 1). - person Ash; 07.03.2016