Почему 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, который действителен только в режиме отладки.