为什么int 3以64位生成SIGSEGV而不是停止调试器?

时间:2010-09-03 08:31:14

标签: debugging assembly signals x86-64

在32位模式编程中,我曾经在我的程序中使用int 3很多用于使用调试器在指定位置停止(将指令嵌入到源中)。现在64位似乎不起作用,在gdb下生成一个非常普通的SIGSEGV并且破坏程序超出希望(“程序终止于信号SIGSEGV,Segmentation fault。 该程序不再存在。“)。我想知道64位模式是否有另一种机制,或者我是否应该做一些缓存 - 刷新(在这种情况下int 3是一个动态生成的操作码(0xcc),是一些jit类似的代码)。

4 个答案:

答案 0 :(得分:20)

__的DebugBreak()

  

今天有一位同事过来询问   如何获得“int 3”功能   64位平台。什么是“int 3”?   这是汇编指令   用于创建断点。至少   这是x86的指令   处理器,你可以想象它   是非常具体的平台。

     

在64位平台上没有   内联汇编,所以有你的   “__asm int 3”。现在做什么?好   有一个鲜为人知的结构   实际上更好用   它适用于所有平台(x64,   Itanium和x86),这是   __debugbreak()。这是一个Visual C ++编译器内在函数(在Visual。中定义)   C ++ 2005下的vc \ include \ intrin.h,   与其他很酷的内在函数)   这将有效地行动“int 3”   跨所有平台。

     

DebugBreak,Win32函数调用是   仍在,但一般使用   __debugbreak()是我的偏好,如果没有其他原因,它不是一个   函数调用(它是一个编译器   内在的),你不需要调试   用于获得可读调用堆栈的符号。

     

如果您正在编写C ++   不想写非便携式   装配,这只是一个   你需要的地方。

http://blogs.msdn.com/b/kangsu/archive/2005/09/07/462232.aspx

答案 1 :(得分:13)

以下代码适用于amd64 UNIX平台:

breakpoint.c

int main() {
    int i;     
    for(i=0; i<3;i++) {
        __asm__("int3");
    }
}

琐碎地编译:{{1​​}}并开始gcc -c breakpoint.c

gdb a.out

你看,gdb在断点处停止。

答案 2 :(得分:12)

啊,我明白了,对不起。我不得不取消保护页面以便执行。 Int 3仍然是一个有效的调试陷阱。

答案 3 :(得分:0)

我建议您永远不要使用asm int 3,因为它适用于所有构建类型。您可能会忘记代码中某处的某条线,这可能意味着很大的麻烦。另一种方法是使用__debugbreak,它仅在调试模式下有效。