Сбой во всех потоках с обработчиком SIGSEGV - PullRequest
0 голосов
/ 27 февраля 2019

Мы разрабатываем процесс в пространстве пользователя, работающий на Linux 3.4.11 во встроенной системе MIPS.Процесс создает несколько (> 10) потоков, используя pthreads.Процесс имеет обработчик сигнала SIGSEGV, который, помимо прочего, генерирует сообщение журнала, которое отправляется в наш файл журнала.Как часть этого потока, он приобретает семафор (плохо, я знаю ...).

Во время нашего тестирования процесс оказался зависшим.В настоящее время мы не можем создать GDB для целевой платформы, поэтому я написал инструмент CLI, который использует ptrace для извлечения значений регистра и данных USER с использованием PTRACE_PEEKUSR.

Что меня удивило, так это то, что все наши потокибыли внутри нашего обработчика сбоев, пытаясь получить семафор.Это (очевидно?) Указывает на тупик на семафоре, что означает, что поток удерживался, удерживая его.Когда я откопал стек, казалось, что почти все потоки (кроме одного) находились в блокирующем вызове (recv, poll, sleep), когда обработчик сигнала начал работать.Ручная реконструкция стека в MIPS - это боль, поэтому мы еще не сделали этого полностью.Один поток оказался в середине вызова malloc, что, по-моему, указывает на его сбой из-за повреждения кучи.

Несколько вещей до сих пор неясны:

1) Предполагается, что одинсбой потока в malloc, почему все остальные потоки будут работать с обработчиком SIGSEGV?Насколько я понимаю, сигнал SIGSEGV доставляется в неисправный поток, нет?Означает ли это, что все наши потоки потерпели крах?

2) Глядя на структуру sigcontext для MIPS, кажется, что она не содержит адрес памяти, к которому был получен доступ (badaddr).Есть ли другое место, где это есть?Я нигде не мог его найти, но мне показалось странным, что он не будет доступен.

И, конечно, если кто-нибудь может предложить способы продолжения анализа, это будет оценено!

1 Ответ

0 голосов
/ 27 февраля 2019

Да, вполне вероятно, что все ваши потоки поочередно зависали, предполагая, что вы правильно зафиксировали состояние потока.

siginfo_t имеет член si_addr, который должен дать вам адресвина.Заполнит ли ваше ядро ​​это другим вопросом.

Внутрипроцессные обработчики сбоев всегда будут ненадежными.Вы должны использовать обработчик вне процесса и установить kernel.core_pattern для его вызова.В современных ядрах нет необходимости записывать файл ядра на диск;вы можете либо прочитать файл ядра из стандартного ввода, либо просто отобразить память процесса зомби (которая все еще доступна, когда ядро ​​вызывает обработчик сбоя).

...