Раскрутить известный стек и указатель инструкций с помощью GDB

У меня есть дамп ядра на Linux x64. В какой-то момент произошел SIGSEGV, и, к сожалению, приложение обработало этот сигнал (но в конце концов все равно не удалось). Таким образом, дамп ядра не содержит непосредственно кадры оригинального SIGSEGV.

Мне удалось определить SP и IP (а также другие регистры) сбойной инструкции. В основном у меня есть полная структура ucontext.

Есть ли способ с GDB/LLDB вместо того, чтобы показывать стеки в потоках, просто раскрутить обратную трассировку из известного SP/IP?


person norekhov    schedule 21.02.2018    source источник


Ответы (2)


Есть ли способ с GDB/LLDB вместо того, чтобы показывать стеки в потоках, просто раскрутить обратную трассировку из известного SP/IP?

RSP и RIP необходимы, но недостаточны: вам также необходимо знать содержимое стека в момент сбоя.

Из вашего описания следует, что ваш обработчик сигналов пытался восстановиться после этого сбоя (возможно, путем siglongjmping out), и в этом случае стек был раскручен, и его содержимое, вероятно, исчезло.

Если это не так, вы можете раскрутить стек вручную, но (насколько я знаю) GDB не поддерживает это. Вам придется изучить дескрипторы очистки (readelf -wf a.out) и выполнить необходимые операции восстановления регистра вручную.

Если ваш двоичный файл был собран с указателями фреймов (это не используется по умолчанию для x86_64 в оптимизированных сборках), это намного проще: вам нужно только восстановить RBP, а затем следовать цепочке указателей фреймов.

person Employed Russian    schedule 21.02.2018
comment
Да, конечно. Обсуждаемое приложение — .NET Core. Я действительно не понимаю, почему они проделали всю эту магию с обработчиками сигналов, в то время как просто сбой на SIGSEGV должен быть в порядке. Во всяком случае, кажется, теперь мне нужно воспроизвести его вживую. - person norekhov; 21.02.2018

У меня была такая же проблема, я думаю, на прошлой неделе. У меня произошел сбой, когда у меня не было основного исполняемого файла или вспомогательных библиотек, поэтому gdb не смог отобразить обратную трассировку библиотеки, которую мне нужно было отлаживать. В итоге я исправил это, изменив основной файл с помощью magic_elf, чтобы RSP и RIP в этом потоке были установлены на регистры, сообщаемые обработчиком segfault.

Я написал небольшую инструкцию о том, как это можно сделать:

http://www.mikekohn.net/software/core_file_analysis.php

person mikeakohn    schedule 13.05.2019