У меня есть две программы: A
и B
. Они разные программы, B
не является вилкой A
. A
запускает B
. Вопрос: могу ли я получить ответную ошибку сегментации B
от A
? Я не могу изменить исходный код программы B
.Получить segfault backtrace дочернего процесса
ответ
Они разные программы, 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
? Возможно, было бы проще иметь A
fork/exec
gdb 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
У меня есть 'B' как двоичный исполняемый файл. 'A' - это программа, которая автоматически тестирует другие программы, предоставляемые программистами участников олимпиады. Благодаря! Я попробую все ваши предлагаемые решения. – melihovv
определенно вы можете. Обычный способ добиться этого - включить выпуклые выпуски, которые содержат послеродовые снимки процесса. Вопрос в том, является ли это доступным для вас ... – user3159253