В чем разница между инструкцией int3 и вызовом __debugbreak? - PullRequest
0 голосов
/ 05 февраля 2019

Что такое __debugbreak?Используется ли он для запуска SIGTRAP?В чем разница между int3 и __debugbreak?

1 Ответ

0 голосов
/ 06 февраля 2019

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
...