代码之家  ›  专栏  ›  技术社区  ›  Joel

Valgrind:故意造成segfault

  •  2
  • Joel  · 技术社区  · 16 年前

    long* ptr = (long *)0xF0000000;
    ptr = 10;
    

    我认为valgrind至少应该把它当作无效的写入,即使它不是分段违规。Valgrind对此只字未提。

    知道为什么吗?

    编辑

    答案已被接受,但我仍然对任何更理智的方法来获取堆栈跟踪的建议投了一些赞成票。..

    6 回复  |  直到 16 年前
        1
  •  7
  •   iblue    14 年前

    只需拨打电话 abort() 。这不是分段故障,但它应该会产生堆芯转储。

        2
  •  5
  •   GManNickG    16 年前

    你错过了一个 * *ptr = 10 ?你拥有的东西无法编译。

    如果确实如此,那么这当然不会导致seg错误,因为你只是在分配一个数字。取消引用可能。

    假设在操作系统上取消对null的引用会导致segfault,以下操作应该可以解决这个问题:

    inline void seg_fault(void)
    {
        volatile int *p = reinterpret_cast<volatile int*>(0);
        *p = 0x1337D00D;
    }
    
        3
  •  5
  •   eyalm    16 年前

    很抱歉提到了显而易见的事情,但为什么不使用带有断点的gdb,然后使用回溯呢?

    (gdb) b somewhere
    (gdb) r
    (gdb) bt
    
        4
  •  3
  •   mark4o    16 年前

    正如其他答案中提到的,你可以打电话 abort() 如果你想完全异常终止你的程序,或者 kill(getpid(), SIGSEGV) 如果必须是分段错误。这将生成一个核心文件,即使您没有在valgrind下运行,也可以与gdb一起使用该文件来获取堆栈跟踪或调试。

    client request 您还可以让valgrind转储带有您自己的自定义消息的堆栈跟踪,然后继续执行。当程序不在valgrind下运行时,客户端请求什么也不做。

    #include <valgrind/valgrind.h>
    ...
    VALGRIND_PRINTF_BACKTRACE("Encountered the foobar problem, x=%d, y=%d\n", x, y);
    
        5
  •  2
  •   piotr    16 年前

    将sig SEGV(11)发送到进程以强制堆芯转储不是更好吗?

        6
  •  2
  •   Roger Lipscombe    10 年前

    你在x86上吗?如果是这样,那么CPU中实际上有一个操作码,意味着“调用可能附加的任何调试器”。这是操作码 CC ,或更常见的称呼 int 3 最简单的触发方式是使用内联组装:

    inline void debugger_halt(void)
    {
    #ifdef MSVC
       __asm int 3;
    #elif defined(GCC)
       asm("int 3");
    #else
    #pragma error Well, you'll have to figure out how to do inline assembly 
                  in your compiler
    #endif
    }
    

    MSVC也支持 __debugbreak() 这是非托管代码中的硬件中断,也是托管代码中MSIL的“中断”。