什么是__debugbreak?它用于触发SIGTRAP吗? int3和__debugbreak有什么区别?
答案 0 :(得分:2)
__debugbreak()
is an intrinsic supported by MSVC将使编译器在针对x86进行编译时发出该指令,或者使任何适合目标ISA的软件断点指令(例如ARM,AArch64等)
ICC也支持它,但是其他编译器(例如gcc)不支持。
您不会在asm中执行call __debugbreak
,您只需编写int3
。例如如果您编译使用它的函数,例如
void foo() {
__debugbreak();
}
Godbolt编译器资源管理器上的MSVC生成以下asm:
void foo(void) PROC ; foo
npad 2
int 3
ret 0
请注意,任何地方都缺少call
指令。即使禁用优化,它也是“内联”的内在函数。这不是“仅仅”一个功能。
这与_mm_mfence()
内在mfence
指令或_mm_popcnt_u64
对于64位操作数大小popcnt
的内在方式相同。
相关:Is there a portable equivalent to DebugBreak()/__debugbreak?
说c有一个__builtin_debugtrap()
。
那里的另一个答案是,假定使用更广泛的GNU C __builtin_trap()
可以停止/中止程序,而不是充当断点。 (因此,gcc在无条件__builtin_trap
之后不会发出任何代码。)
更新:显然,MSVC 确实允许您获取其地址,所以我猜想它的某个库版本在某个地方。所以您可以在asm中编写call __debugbreak
,但是您不会,因为它毫无意义。
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; }
编译为(on Godbolt)
void (__cdecl*getFunc(void))(void) PROC ; getFunc
lea rax, OFFSET FLAT:__debugbreak
ret 0