C Valgrind:故意造成故障

C Valgrind:故意造成故障,c,segmentation-fault,valgrind,C,Segmentation Fault,Valgrind,这是一个疯狂的黑客行为,但我试图在执行过程中的某个特定点故意造成segfault,因此valgrind将给我一个堆栈跟踪 如果有更好的方法,请告诉我,但我仍然想知道如何谨慎地导致SEGFULT,以及我的尝试失败的原因 这是我失败的尝试: long* ptr = (long *)0xF0000000; ptr = 10; 我认为valgrind至少应该把它看作是一个无效的写入,即使它不是一个分段冲突。瓦尔格林对此只字未提 你知道为什么吗 编辑 答案被接受,但我仍然有一些赞成票支持任何关于获取堆栈

这是一个疯狂的黑客行为,但我试图在执行过程中的某个特定点故意造成segfault,因此valgrind将给我一个堆栈跟踪

如果有更好的方法,请告诉我,但我仍然想知道如何谨慎地导致SEGFULT,以及我的尝试失败的原因

这是我失败的尝试:

long* ptr = (long *)0xF0000000;
ptr = 10;
我认为valgrind至少应该把它看作是一个无效的写入,即使它不是一个分段冲突。瓦尔格林对此只字未提

你知道为什么吗

编辑


答案被接受,但我仍然有一些赞成票支持任何关于获取堆栈跟踪的更合理方法的建议…

您是否缺少
*
中的
*ptr=10
?你所拥有的不会被编译

如果是这样的话,那当然不会导致seg故障,因为您只是分配了一个数字。取消引用可能会导致错误

假设在操作系统上取消对null的引用会导致segfault,下面的操作应该可以做到这一点:

inline void seg_fault(void)
{
    volatile int *p = reinterpret_cast<volatile int*>(0);
    *p = 0x1337D00D;
}
inline void seg_故障(void)
{
volatile int*p=reinterpret_cast(0);
*p=0x1337D00D;
}

您在x86上吗?如果是这样,那么CPU中实际上有一个操作码,表示“调用可能附加的任何调试器”。这是操作码
CC
,或者更常见的称为
int3
。触发它的最简单方法是使用内联程序集:

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还支持
\uu debugbreak()
,这是非托管代码中的硬件中断和托管代码中的MSIL“中断”。

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

很抱歉提到了显而易见的问题,但为什么不将gdb与中断点一起使用,然后使用回溯

(gdb) b somewhere
(gdb) r
(gdb) bt

只需调用
abort()
。它不是一个segfault,但应该生成一个核心转储。

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

#include <valgrind/valgrind.h>
...
VALGRIND_PRINTF_BACKTRACE("Encountered the foobar problem, x=%d, y=%d\n", x, y);
使用valgrind,您还可以让valgrind使用您自己的自定义消息转储堆栈跟踪,然后继续执行。当程序未在valgrind下运行时,客户端请求不执行任何操作

#include <valgrind/valgrind.h>
...
VALGRIND_PRINTF_BACKTRACE("Encountered the foobar problem, x=%d, y=%d\n", x, y);
#包括
...
VALGRIND_PRINTF_BACKTRACE(“遇到了foobar问题,x=%d,y=%d\n”,x,y);

long*紧靠着类型“long*”我还没有决定我更喜欢哪种形式——“long*ptr”、“long*ptr”、“long*ptr”那是如何编译的呢?你用的是什么编译器?C指针风格:这就是我的想法,但我对gdb的经验不足,不知道如何使用。:)通常,您无法从进程外部知道执行期间的确切时间点(您希望在该时间点发送SIGSEGV)。进程可以将SIGSEGV发送到自身:
kill(getpid(),SIGSEGV)相关: