LINUX.ORG.RU

Как узнать последние выполненные перед завершением методы?

 ,


0

1

Добрый день. Мне в качестве наследия былых времен досталась софтина, написанная частично на С, частично на С++, частично левой ногой.

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

Суть: в течении некоторого времени, от 2мин до пары часов, программа завершается с кодом 0, то есть вполне корректно. При этом не используется exit(0) вообще нигде. Выход из main всего один и попадать туда программа не должна - перед «return 0» есть блокирующий вызов.

Можно как-то при помощи GDB или других средств просмотреть последние 10/100/etc вызовов функций этой программы, чтобы найти точку выхода? Софтина многопоточна ко всему прочему.

★★

Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от EXL

Если вы про «bt» из GDB, то оно говорит что то типо «No stack».

Dikar ★★
() автор топика

Выход из main всего один и попадать туда программа не должна - перед «return 0» есть блокирующий вызов

Что за вызов?

Можно как-то при помощи GDB или других средств просмотреть последние 10/100/etc вызовов функций этой программы, чтобы найти точку выхода?

При желании извратиться можно, но зачем? Если действительно стоит «блокирующий» вызов, то это мало чем поможет и будет походить на удаление гланд через задницу. Нужно смотреть что за вызов, как из него можно выйти и искать в коде где это происходит.

mashina ★★★★★
()

Полностью под дебагером приложение можно запустить? Тогда можно попробовать через atexit установить обработчик и в дебагере поставить туда точку останова, если есть где-то exit вне main, то backtrace его покажет, если выход через main - это тоже видно будет. и до кучи на тот «блокирующий вызов» тоже поставить брякпойнт. После чего остается только откинуться на спинку стула и ждать.

На всякий случай спрошу - а вы точно уверены, что «0» это именно ваш код завершения?

Vinick ★★
()

Может, это какой-то коллбечный обработчик ошибок по типу иксового. Какая-то сторонняя либа может внутри поставить свой, который дёргает exit(). Запустить под gdb/приаттачится gdb, поставить брейкпоинт на exit, и ждать, не? Ну и понатыкать 100500 логов в свои функции при этом тоже не помешает.

ilammy ★★★
()
Последнее исправление: ilammy (всего исправлений: 1)
Ответ на: комментарий от Vinick

Ставить брейкпоинт на блокирующий вызов - интересное предложение) логика скрыта глубоко в коде - этот вызов запускает докодирование радиосигнала при помощи библиотеки gnu radio, вероятность появления ошибки в которой невелика.

То что возвращается ноль я уверен - echo $? печатает 0.

По поводу atexit() спасибо, не думал об этом, попробую.) но я делал grep -r по исходникам и больше точек выхода не нашел, может упустил чего...

Dikar ★★
() автор топика
Ответ на: комментарий от Dikar

я решил, что под «блокирующим вызовом», подразумевается какая-то функция, которая вызывается непосредствено перед return из main и никогда не возвращает управление. Но по-настоящему блокирует только «for(;;);», все остальное может разблокироваться. Вставить отладочную печать перед return из main все равно не помешает.

Vinick ★★
()
Ответ на: комментарий от Vinick

Это тоже верно. Сделаю. Спасибо за совет.

Dikar ★★
() автор топика

В gdb есть обратная отладка. В определённый момент можно начать запись и все происходящие изменения в коде будут записываться. Потом можно делать шаги назад. Что-то типа step, только reverse-step. Тормозит эта штука ужасно; помогает только скриптование точек останова для запуска записи только перед самым интересным местом. Но даже так это всё равно ооочень медленно.

Где-то мелькала реклама коммерческих отладчиков, которые хвастались замедлением всего в два раза.

i-rinat ★★★★★
()
Ответ на: комментарий от Adonai

Спасибо, уже нашел при помощи GDB проблему - в одном из потоков был SIGPIPE. Не понимаю почему сначала gdb говорило no stack

Dikar ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.