2016-05-01 5 views
1

У меня есть две программы: A и B. Они разные программы, B не является вилкой A. A запускает B. Вопрос: могу ли я получить ответную ошибку сегментации B от A? Я не могу изменить исходный код программы B.Получить segfault backtrace дочернего процесса

+1

определенно вы можете. Обычный способ добиться этого - включить выпуклые выпуски, которые содержат послеродовые снимки процесса. Вопрос в том, является ли это доступным для вас ... – user3159253

ответ

1

Они разные программы, B не является ответвлением A. A запускает B

Под "запуска", я полагаю, вы имеете в виду, что A делает fork и ребенок делает execvp из B

Я не могу изменить исходный код программы B.

Это означает, что вы есть источник B, но можете не изменить его, но может пересобрать его с -g, -O0 и другими вещами, как -fno-omit-frame-pointer получить отладочные символы и больше шансов на более точную трассировку стека.

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

Я также заключу, что вы имеют источник для A [и может делать все, что необходимо, чтобы все работало].

Вопрос: могу ли я получить ответную ошибку сегментации B от A?

Да. Существует несколько разных способов.

A можно использовать ptrace при вызове B так же, как gdb или strace бы. Когда B segfaults, A может получить контроль и пройти назад стек и распечатать его.

Но это задает вопрос: является ли ваша основная цель [просто] отлаживать B? Возможно, было бы проще иметь Afork/execgdb B вместо B, так что gdb может выполнять «тяжелый подъем», поскольку трассировка стека - это простая команда gdb. Еще более простой способ - позволить B сбрасывать ядро, разрешая ограничение в команде оболочки и затем анализируя основной файл с gdb.

Другая возможная опция. Посмотрите на символы в B, используя readelf и список разделяемых библиотек, которые ему нужны, через ldd. Затем вы можете решить, имеет ли B какие-либо «крюковые» точки. То есть любые символы, которые он хочет вызывать из общей библиотеки, такой как open.

Вы можете создать специальную общую библиотеку с open, а затем «принудительно» ее на B, установив переменную окружения LD_PRELOAD. Затем, когда B звонит open, ваша общая библиотека получает контроль. Затем вы можете установить обработчик сигнала для SIGSEGV, а затем с помощью dlsym получите адрес «реального» и завершите вызов open.

Теперь, когда B segfaults, обработчик сигналов в вашей специальной общей библиотеке может пройти стек через __builtin_return_address et. и др. и сообщить результаты обратно A (через трубу или гнездо)

Еще один способ заключается в взламывать вверх B исполняемый файл и добавить крючок таким образом, который взаимодействует с A

+0

У меня есть 'B' как двоичный исполняемый файл. 'A' - это программа, которая автоматически тестирует другие программы, предоставляемые программистами участников олимпиады. Благодаря! Я попробую все ваши предлагаемые решения. – melihovv

Смежные вопросы