Я написал эту простую программу в NASM, я знаю, что Linux завершает программу, когда стек перерастает в программный код, но как бы я отлаживал такую проблему в реальном сценарии, явно игнорируя тот факт, что этого никогда не должно происходить.
section .data
section .bss
section .text
global _start
_start:
nop
mov eax,42
SillyLoop: push eax
jmp SillyLoop
nop
Когда я запускаю gdb, я получаю
Continuing.
Program received signal SIGSEGV, Segmentation fault.
SillyLoop () at sandbox.asm:10
Это не очень полезно, как мне извлечь больше информации (в реальной программе)?
Это не очень полезно, как мне извлечь больше информации (в реальной программе)?
Вы можете проверить стек вызовов с помощью команды where
(здесь это не поможет, так как в стеке есть только одна подпрограмма) и проверить текущую ошибочную инструкцию с помощью x/i $pc
. Данный:
(gdb) x/i $pc
=> 0x8049006 <SillyLoop>: push %eax
вы можете сразу сказать, что со стеком что-то не так (поскольку это единственная причина, по которой PUSH
может выйти из строя) — либо ваш ESP
облажался, либо у вас закончился стек. Изучение указателя стека с помощью info reg esp
(который печатает 0xff7fe000
) дает еще одну подсказку: вы находитесь на границе страницы.
Но, в конце концов, программирование на ассемблере похоже на использование очень острого ножа — вам нужно знать, что вы делаете, иначе вы можете написать программу, которую будет сложно отлаживать.
Я бы рекомендовал запускать программу через
valgrind
. Он бы сказал вам причину.