Подтвердить что ты не робот

Можно ли использовать libSegFault.so для получения обратных путей для SIGABRT?

Волшебное заклинание

LD_PRELOAD=/lib/libSegFault.so someapp

запускает someapp с помощью libSegFault.so, предоставляя обратную информацию на SIGSEGV, как описано в many разные места.

Помимо использования signal(7) -подобных подходов, чтобы вызвать SIGABRT для вызова обработчика SIGSEGV, есть ли способ получить libSegFault для предоставления информации о backtrace для отказов assert(3)?

4b9b3361

Ответ 1

env SEGFAULT_SIGNALS="abrt segv" LD_PRELOAD=/lib/libSegFault.so someapp

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

env SEGFAULT_SIGNALS="abrt segv" LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so some-64bit-app

или

env SEGFAULT_SIGNALS="abrt segv" LD_PRELOAD=/lib/i386-linux-gnu/libSegFault.so some-32bit-app

в зависимости от того, выполнялось ли приложение, которое я запускал, было скомпилировано 64-битное или 32-битное. (Вы можете использовать file для проверки.)


source сообщает, что существуют три переменные среды, которые определяют поведение libSegFault.so:

  • SEGFAULT_SIGNALS: список сигналов, которые вызывают трассировку стека. По умолчанию используется SIGSEGV. Определенный, но пустой SEGFAULT_SIGNALS означает, что никакие сигналы не вызывают трассировку стека. Поддерживаемые значения segv, ill, abrt, fpe, bus для систем, которые имеют сигнал SIGBUS, stkflt для систем, имеющих сигнал SIGSTKFLT, и all для всех этих.

  • SEGFAULT_USE_ALTSTACK: Если определено в среде, libSegFault.so использует альтенный стек для сигналов трассировки стека. Это может пригодиться, если вы отлаживаете повреждение стека.

  • SEGFAULT_OUTPUT_NAME: Если определено в среде, трассировка стека записывается в этот файл вместо стандартной ошибки.

Честно говоря, я сначала нашел их, изучив библиотеку с помощью strings /lib/libSegFault.so | sed -e '/[^0-9A-Z_]/ d'. Все стандартные библиотеки (libSegFault.so, ставшие частью библиотеки GNU C) настраиваются через переменные среды, поэтому использование чего-то вроде этой команды для выгрузки любых строк, которые выглядят как имена переменных среды, - это быстрый способ найти материал для поиска. Выполнение веб-поиска по "SEGFAULT_SIGNALS" "SEGFAULT_OUTPUT_NAME" создает ряд полезных ссылок; видя, что он был частью библиотеки GNU C в настоящее время, я перешел в архивы source git, нашел фактический исходный файл для библиотеки, и отправил мой ответ.

Ответ 2

В аналогичном ключе обработчик исключений glibc записывает дамп стека /dev/console при ошибках повреждения кучи.

Если вы выполняете свой исполняемый файл в режиме non tty (т.е. в процессе systemd или другом отсоединенном процессе), выход сбоя переходит в /dev/null, что не так полезно.

Существует недокументированная функция для перенаправления вывода на /dev/stderr. Задайте следующую переменную среды:

export LIBC_FATAL_STDERR_=1

Это можно использовать в сочетании с libSegFault.so для максимальной криминалистики.

Также стоит упомянуть, что это может дать вам две трассировки стека, если вы также включите обратные трассировки для SIGABRT, поскольку glibc сначала выполняет трассировку стека, затем передает SIGABRT..., а затем libSegFault дает вторую трассировку стека.