int3
- это инструкция x86 .
__debugbreak()
- это свойственный , поддерживаемый MSVC , который доставит компилятор ввыдает эту инструкцию при компиляции для x86 или любой другой программной точки останова, подходящей для целевого ISA (например, ARM, AArch64 и т. д.)
ICC также поддерживает ее, но другие компиляторы (например, gcc) этого не делают..
Вы не станете делать call __debugbreak
в асме, вы просто напишите int3
.например, если вы компилируете функцию, которая ее использует, например,
void foo() {
__debugbreak();
}
MSVC в проводнике компилятора Godbolt, выдает такую команду:
void foo(void) PROC ; foo
npad 2
int 3
ret 0
Обратите внимание на отсутствие инструкции call
в любом месте.Это встроенная функция, даже если оптимизация отключена.Это не просто функция.
Это то же самое, что _mm_mfence()
является свойством для инструкции mfence
или _mm_popcnt_u64
для 64-битного размера операнда popcnt
.
Связанный: Есть ли переносимый эквивалент DebugBreak () / __ debugbreak?
говорит, что у clang есть __builtin_debugtrap()
.
Другой ответ тамговорит, что более широко доступный GNU C __builtin_trap()
должен останавливать / прерывать программу, а не действовать как точка останова.(Таким образом, gcc не выдаст никакого кода после безусловного __builtin_trap
.)
обновления: очевидно MSVC действительно позволяет вам взять его адрес, так что я думаю, что тамэто где-то его библиотечная версия. Таким образом, вы могли бы писать call __debugbreak
в asm, но вы все равно не , потому что это бессмысленно.
GCC не позволяет вам взять адрес встроенных, например, при попытке компиляции:
int (*getbuiltin(void))(unsigned) { return &__builtin_popcount; }
выдает эту ошибку:
error: built-in function '__builtin_popcount' must be directly called
Но MSVC и ICC компилируютсяvoid (*getFunc(void))(void) { return &__debugbreak; }
в это ( на Годболт )
void (__cdecl*getFunc(void))(void) PROC ; getFunc
lea rax, OFFSET FLAT:__debugbreak
ret 0