реконструировать трассировку стека отчета о диагностике пользователя OSX

Я хотел бы выяснить, где именно приложение, написанное на C/C++, дает сбой. Я не могу отлаживать приложение напрямую, ни с помощью gdb/lldb, ни с помощью IDE, потому что приложение запускается программой (это контроллер робота для программного обеспечения для моделирования роботов webots). В консоли OSX я могу найти «Отчет о диагностике пользователя», в котором даже показана трассировка в момент сбоя. Мне просто нужно выяснить, где именно в моем исходном коде происходит сбой, но я не понимаю следующий синтаксис трассировки стека:

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       EXC_I386_GPFLT

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_c.dylib               0x00007fff92d6b859 strtol_l + 77
1   controller_2                    0x0000000100006b57 main + 4839
2   controller_2                    0x00000001000010b4 start + 52

По-видимому, где-то (+4839) в моей функции int main() {} что-то в конце концов вызывает strtol_l (должно быть косвенным, потому что в коде контроллера нет вызова этой функции), что вызывает сбой.

Что означает + 4839? это смещение блока памяти? Это не может быть номер строки исходного кода, так как исходный код для контроллера составляет всего около 1200 строк, а контроллер не скомпилирован с отладочной информацией.


person Michael Trouw    schedule 29.05.2015    source источник
comment
Я бы сказал, что + 4839 говорит, что он вызвал strtol_l в 4839-й инструкции процессора после того, как ввел main. Если вы дизассемблируете запущенный вами двоичный файл, вы сможете найти, что это за инструкция, и, возможно, найти ссылку на знакомую строку кода в окружающей сборке.   -  person nonsensickle    schedule 29.05.2015
comment
Это количество байтов, смещение от начала main.   -  person user3386109    schedule 29.05.2015
comment
если вы перекомпилируете код контроллера с параметром «-ggdb» (что сделает исполняемый файл значительно больше), а затем дайте ему работать до тех пор, пока он не выдаст ошибку, тогда трассировка стека будет включать номера строк и т. д. и т. д.   -  person user3629249    schedule 29.05.2015
comment
при сбое сегмента программного обеспечения контроллера он выводит «основной» файл. используйте этот основной файл в качестве входных данных для gdb. (иметь весь исходный код, видимый для gdb, и исходный исполняемый файл, сгенерированный с использованием (по крайней мере, «-g» и предпочтительно «-ggdb»). Тогда все детали обратной трассировки (при следующем сбое seg) будут видны, с вызовом функции имена, номера строк и т. д. Примечание: поскольку вы, вероятно, не компилировали библиотеки из исходного кода, детали внутри библиотечных функций все равно будут довольно скудными, однако корень проблемы в вашей основной функции будет очень заметен.   -  person user3629249    schedule 29.05.2015
comment
Ответ на этот вопрос может вас заинтересовать: stackoverflow.com/questions/16227845/   -  person Jeremy Friesner    schedule 29.05.2015
comment
Отлично, спасибо за комментарии, я попытаюсь скомпилировать с -ggdb и позволить симам работать, пока это не произойдет, а затем выяснить, в чем была причина, если диагностический отчет OSX включает номера строк и имена вызовов функций, которые есть. Если я смогу найти проблему в моей основной функции, это нормально, я не думаю, что в libsystem_c.dylib есть ошибка, по крайней мере, я не надеюсь, что она есть..   -  person Michael Trouw    schedule 31.05.2015
comment
Компиляция с -g или даже -ggdb работала, но моя программа не падала с тех пор, как я ее запускал. Использование otool -tv в скомпилированном объектном файле дает мне ассемблер, похожий на тарабарщину, и я не могу прочитать какие-либо полезные сигнатуры функций: pastebin.com/33uACurn запуск otool -tv в файле .out также дает ту же тарабарщину, но теперь с некоторыми дополнительными функциями, такими как подписи. Где заканчивается «основной» файл? Я пытался найти его, но не знаю, где искать. Как еще, кроме использования otool, я могу дизассемблировать бинарник?   -  person Michael Trouw    schedule 25.06.2015


Ответы (1)


Вы можете отладить процесс контроллера робота в gdb, используя команду gdb attach с PID процесса контроллера робота, который вы хотите отлаживать. Это позволит gdb подключать процесс на лету и отлаживать его, как если бы он изначально был запущен из gdb. Это хорошо объяснено в документации Webots здесь: http://www.cyberbotics.com/dvd/common/doc/webots/guide/section5.5.html

person Olivier Michel    schedule 29.05.2015
comment
Хорошо, да, вы действительно можете, но в моем случае это довольно сложно/нереально сделать, я думаю. Я запускаю 150 * 10 симуляций, и сбои происходят в случайное время (недетерминированное). Мне пришлось бы написать скрипт, который находит PID всех 2 * 14 контроллеров, прикрепляет все эти PID к GDB для каждой из всех 1500 симуляций. и я предполагаю, что после каждой симуляции выйдите из GDB. Я не думаю, что это самый простой способ выяснить, в чем проблема :/ - person Michael Trouw; 31.05.2015
comment
Затем, возможно, вы можете попробовать установить gdb в качестве программы контроллера ваших роботов и установить в поле controllerArg имя фактического контроллера, который вы хотите отладить, плюс с опцией -x с командой запуска, чтобы gdb начал запускать контроллер немедленно. Однако я не уверен, что это произойдет, когда один из ваших контроллеров выйдет из строя. Я думаю, вы должны запустить веб-ботов из консоли, чтобы увидеть там вывод gdb. Дайте нам знать, если это работоспособное решение. - person Olivier Michel; 01.06.2015
comment
Хм, я думаю (раньше не был уверен), что segfault полностью приводит к сбою MacPro. Он разбился ранее (я использую TeamViewer для удаленного мониторинга запущенных симуляций MacPro, и в какой-то момент экран гаснет, и соединение теряется. Затем мне приходится физически перезагружать MacPro). Поскольку это только что произошло, я надеюсь, что кто-нибудь сможет перезагрузить компьютер. MacPro мне завтра или еще после работы буду знать, возможно ли это сделать. Я добавил -ggdb в качестве флага компиляции, поэтому мне любопытно, смогу ли я теперь увидеть более подробную информацию о трассировке стека в отчете о диагностике пользователя. Обновлю, как только узнаю больше! - person Michael Trouw; 04.06.2015
comment
Установка gbd в качестве программы-контроллера не сработала. наличие структуры папок /controllers/gdb/gdb, где gdb является символической ссылкой на /usr/local/bin/gdb, не работает. Я пробовал то же самое для lldb, не сработало. Хотя это будет лучший вариант. Я читал, что gdb и lldb поддерживают отладку нескольких потоков/процессов, поэтому это должно быть возможным. Я думаю о написании нового контроллера, который выполняет системный вызов gdb для запуска реального контроллера. это сработает? - person Michael Trouw; 25.06.2015
comment
Я не вижу, это не сработает. Это явно стоит попробовать... Держите нас в курсе. - person Olivier Michel; 26.06.2015