Вопрос по assembly, x86-64, c, linux – Найти, какая инструкция по сборке вызвала ошибку Illegal Instruction без отладки

25

При запуске программы, которую я написал на ассемблере, я получаюIllegal instruction ошибка. Есть ли способ узнать, какая инструкция вызывает ошибку, без отладки, потому что на машине, на которой я работаю, нет отладчика или какой-либо системы разработки. Другими словами, я компилирую на одной машине и запускаю на другой. Я не могу проверить свою программу на компьютере, который я компилирую, потому что они не поддерживают SSE4.2. Машина, на которой я запускаю программу, тем не менее поддерживает инструкции SSE4.2.

Я думаю, что это возможно, потому что мне нужно сказать ассемблеру (YASM) распознавать инструкции SSE4.2, так же, как мы делаем с gcc, передавая-msse4.2 флаг. Или ты думаешь это не причина? Есть идеи, как сказать YASM распознавать инструкции SSE4.2?

Может быть, я должен пойматьSIGILL сигнал, а затем декодировать SA_SIGINFO, чтобы увидеть, какую незаконную операцию выполняет программа.

YASM распознает инструкции SSE4.2, так что это не проблема. Вы уверены, что ваша машина поддерживает SSE4.2? Какое оборудование это точно? Вы можете запустить программу в эмуляторе, вероятно, подойдет valgrind (который поддерживает подмножество SSE4.2, которое используется в glibc и gcc). Gunther Piez

Ваш Ответ

6   ответов
2

return оператор в конце функции может вызвать это.

31

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

4

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

Тогда вы увидите, как далеко вы доберетесь ...

(Кстати, хороший редактор и хорошее понимание синтаксиса макросов на ассемблере спасают жизнь при написании машинного кода.)

Error: User Rate Limit Exceeded pythonic
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
11

просто запустите программу, дайте ей аварийно завершить работу, затем извлеките дамп ядра с целевой машины на свою машину разработки и загрузите его в GDB, созданную для отладки целевой архитектуры - это должно точно сказать вам где произошла авария. Просто используйте GDBcore Команда для загрузки файла ядра в отладчик.

To enable core dumps on the target:

ulimit -c unlimited

pseudo-files that control how the core file will be named (cat these to see the current configuration, write to them to change the configuration):

/proc/sys/kernel/core_pattern
/proc/sys/kernel/core_uses_pid

В моей системе, после того, как дампы ядра включены, аварийно завершающая программа запишет файл с именем «core». в рабочем каталоге. Это, вероятно, достаточно хорошо для ваших целей, но изменение имени файла дампа основной памяти позволяет вам вести историю дампов ядра, если это необходимо (возможно, для более неустойчивой проблемы).

Error: User Rate Limit ExceededcoreError: User Rate Limit Exceeded
Error: User Rate Limit Exceededcore.$PID.
21

программа прервана сигналом + недопустимый сигнал инструкции). Вот как я выяснил, какая инструкция вызывала сбой.

Сначала я включил дампы ядра:

$ ulimit -c unlimited

Интересно, что папка, из которой я запускал бинарный файл, содержала папку с именемcore, Мне пришлось сказать Linux добавить PID в дамп ядра:

$ sudo sysctl -w kernel.core_uses_pid=1

Затем я запускаю свою программу и получаю ядро с именемcore.23650, Я загрузил двоичный файл и ядро с помощью GDB.

$ gdb program core.23650

Как только я попал в GDB, он показал следующую информацию:

Program terminated with signal SIGILL, Illegal instruction.
#0  0x00007f58e9efd019 in ?? ()

Это означает, что моя программа потерпела крах из-за недопустимой инструкции на0x00007f58e9efd019 адресная память. Затем я переключился наasm layout проверить последнюю выполненную инструкцию:

(gdb) layout asm
>|0x7f58e9efd019  vpmaskmovd (%r8),%ymm15,%ymm0
 |0x7f58e9efd01e  vpmaskmovd %ymm0,%ymm15,(%rdi)
 |0x7f58e9efd023  add    $0x4,%rdi
 |0x7f58e9efd027  add    $0x0,%rdi

Это была инструкцияvpmaskmovd это вызвало ошибку. По-видимому, я пытался запустить программу, предназначенную для архитектуры AVX2, в системе, в которой отсутствует поддержка набора инструкций AVX2.

$ cat /proc/cpuinfo | grep avx2

Наконец, я подтвердилvpmaskmovd - это инструкция только для AVX2.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
4

вы можете вставить распечатки трассировки, чтобы вы могли быстро исключить большие области кода. Как только вы это сделаете, запустите, например,

$ objdump --disassemble my-crashing-program | less

Затем перейдите, например, к функция, которую вы знаете, вызывает ошибку, и читайте код, ища что-то странное.

Я не совсем уверен, какobjdump отображает недопустимые инструкции, но они должны выделяться.

Похожие вопросы