这是 mad-hack ,但我试图故意在执行的某个特定点引起段错误,所以valgrind会给我一个堆栈跟踪。
如果有更好的方法可以告诉我,但我仍然很想知道如何故意导致段错误,以及为什么我的尝试不起作用。
这是我失败的尝试:
long* ptr = (long *)0xF0000000;
ptr = 10;
我认为valgrind至少应该将其视为无效写入,即使它不是分段违规。 Valgrind对此一无所知。
任何想法为什么?
修改
接受了答案,但我仍然有一些建议可以获得更合理的方法来获得堆栈跟踪......
答案 0 :(得分:7)
只需致电abort()
即可。这不是一个段错误,但它应该产生一个核心转储。
答案 1 :(得分:5)
您是否遗漏了*
中的*ptr = 10
?你有什么不会编译。
如果确实如此,那当然不会导致seg-fault,因为你只是分配一个数字。解除引用可能。
假设您的操作系统上取消引用null会导致段错误,以下应该可以解决这个问题:
inline void seg_fault(void)
{
volatile int *p = reinterpret_cast<volatile int*>(0);
*p = 0x1337D00D;
}
答案 2 :(得分:5)
很抱歉提到明显但为什么不使用带有断点的gdb然后使用backtrace?
(gdb) b somewhere
(gdb) r
(gdb) bt
答案 3 :(得分:3)
如其他答案中所述,如果您想完全异常终止程序,可以致电abort()
,如果必须是分段错误,则可以kill(getpid(), SIGSEGV)
。这将生成一个核心文件,即使您没有在valgrind下运行,也可以使用gdb来获取堆栈跟踪或调试。
使用valgrind client request你也可以让valgrind使用你自己的自定义消息转储堆栈跟踪,然后继续执行。当程序未在valgrind下运行时,客户端请求不执行任何操作。
#include <valgrind/valgrind.h>
...
VALGRIND_PRINTF_BACKTRACE("Encountered the foobar problem, x=%d, y=%d\n", x, y);
答案 4 :(得分:2)
你是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“中断”。
答案 5 :(得分:2)
将SIGV(11)发送到强制核心转储的进程不是更好吗?