Почему int 3 генерирует SIGSEGV в 64-битном режиме вместо остановки отладчика?
В 32-битном режиме программирования я использовал int 3
в моих программах много для остановки в заданном месте с помощью отладчика (вложение инструкции в исходный код). Теперь в 64 бит, похоже, он не работает, создавая очень обычный SIGSEGV под gdb и уничтожая программу без надежды ("Программа завершена сигналом SIGSEGV, ошибка сегментации.
Мне кажется, что в 64-битном режиме есть другой механизм, или если я должен выполнить кеш-флеш (int 3
- это динамически генерируемый код операции в этом случае (0xcc), это некоторая джит-подобная код).
Ответы
Ответ 1
Ответ BarsMonster показывает, что __asm__("int3");
не будет работать на 64-битных платформах. Это - по крайней мере сегодня (2014) - не верно.
Следующий код будет работать на платформе amd64
:
breakpoint.c
int main() {
int i;
for(i=0; i<3;i++) {
__asm__("int3");
}
}
Скомпилируйте его тривиально: gcc -c breakpoint.c
и запустите gdb a.out
:
(gdb) run
Starting program: /tmp/a.out
Program received signal SIGTRAP, Trace/breakpoint trap.
0x00000000004004fb in main ()
Вы видите, gdb останавливается в точке останова.
Ответ 2
__ DebugBreak()
Сегодня коллега пришел, чтобы спросить о как получить функциональность "int 3" на 64-битные платформы. Что такое "int 3" ? Это инструкция сборки, которая используется для создания точки останова. Как минимум что инструкция для x86 процессор, и, как вы можете себе это представить очень специфична для платформы.
На 64-битных платформах нет встроенная сборка, так что "__asm int 3". Что делать сейчас? Что ж существует менее известная конструкция, которая на самом деле гораздо лучше использовать в этом он работает на всех платформах (x64, Itanium и x86), что __debugbreak(). Это встроенный в Visual С++ компилятор (определенный в Visual С++ 2005 под vc\include\intrin.h, с тоннами других прохладных свойств) который будет эффективно действовать "int 3" , на всех платформах.
DebugBreak, вызов функции Win32 все еще вокруг, но в целом с использованием __debugbreak() - это мое предпочтение, если не по какой-либо другой причине, вызов функции (это компилятор intrinsic), и вам не нужно отлаживать символов, чтобы получить считываемый стек вызовов.
Если вы пишете С++, вы, вероятно, не хотят писать не переносные сборка, и это всего лишь одно меньше где вам нужно будет.
http://blogs.msdn.com/b/kangsu/archive/2005/09/07/462232.aspx
Ответ 3
А, я понял, извините. Мне пришлось снять защиту страниц для выполнения. Int 3 по-прежнему является допустимой ловушкой отладки.
Ответ 4
Я рекомендую никогда не использовать asm int 3
, поскольку он работает для всех типов сборки. Вы можете забыть строку где-то в своем коде, и это может означать большие проблемы. Альтернативой является использование __ debugbreak, который действителен только в режиме отладки.