我正在尝试编写一个与另一个容易崩溃的进程(不在我的控制范围内)交互的Python程序。不幸的是,我正在交互的程序甚至不能可靠地崩溃!因此,我想制作一个快速的C++程序来有意地崩溃,但实际上我并不知道最好和最短的方法是什么,是否有人知道在这之间应该放些什么:
int main() {
crashyCodeGoesHere();
}
为了让我的C++程序可靠地崩溃
abort()
函数可能是您最好的选择。它是 C 标准库的一部分,并被定义为“导致异常程序终止”(例如,致命错误或崩溃)。
abort()
引起的程序崩溃不会调用任何析构函数或 atexit
函数,但在这里可能并不重要。 - Xeoatexit
函数,那么现在就不会崩溃了,对吗? - Donal Fellowsabort()
是正确的答案,那么exit(-1);
是否可接受? - asir6abort()
会触发像crashpad这样的东西吗?我想崩溃我的应用程序是为了确保崩溃报告正常工作。 - Ben尝试:
raise(SIGSEGV); // simulates a standard crash when access invalid memory
// ie anything that can go wrong with pointers.
发现于:
#include <signal.h>
signal()
可以捕获信号。但大多数正常的应用程序并不这样做。 - user149341raise()
。这让您仅通过更改参数就可以测试大量不同类型的异常。 - user836352除以零会导致应用程序崩溃:
int main()
{
return 1 / 0;
}
main
函数的全部代码被删除,包括ret
指令。程序执行可能直接跳转到后面的函数中。 - usr*((unsigned int*)0) = 0xDEAD;
那么,我们是在堆栈溢出上吗?
for (long long int i = 0; ++i; (&i)[i] = i);
(没有任何标准可以保证会崩溃,但是包括被接受的答案在内,建议的所有答案都不能保证不会崩溃,因为SIGABRT
其实也可能被捕获。在实践中,这个代码会在任何地方都崩溃。)
(&i)[i] += !i
,但我担心编译器可能会聪明到想要优化掉它。 :-) - sam hocevar throw 42;
只需要答案... :)
assert(false);
保证导致崩溃:
如果定义了NDEBUG[...]则简单地定义断言宏为空操作。
也就是说,当未定义NDEBUG时,assert(false);
将终止程序并生成错误消息。
#define assert(ignore) ((void)0)
每次包含头文件时,断言宏会根据NDEBUG的当前状态进行重新定义。
断言宏将诊断测试放入程序中;当表达式(必须具有标量类型)为false时[...]。然后调用abort函数。
assert
被等同于((void)0)
。 - Seth Carnegie由于崩溃是调用未定义行为的症状,并且调用未定义行为可能导致任何结果,包括崩溃。因此,我认为您不想真正使程序崩溃,而只是让其进入调试器。最可移植的方法可能是使用abort()
。
虽然 raise(SIGABRT)
有相同的效果,但写起来更复杂。无论哪种方式都可以通过为 SIGABRT
安装信号处理程序来拦截。因此,根据您的情况,您可能需要引发其他信号。例如SIGFPE
、SIGILL
、SIGINT
、SIGTERM
或 SIGSEGV
,但它们也都可以被拦截。
当您可以不考虑可移植性时,您的选择可能更广泛,比如在Linux上使用SIGBUS
。
答案因平台而异,取决于您的目标。但这里是 Mozilla JavaScript 崩溃函数,我认为它展示了许多使其工作具有挑战性的问题:
static JS_NEVER_INLINE void
CrashInJS()
{
/*
* We write 123 here so that the machine code for this function is
* unique. Otherwise the linker, trying to be smart, might use the
* same code for CrashInJS and for some other function. That
* messes up the signature in minidumps.
*/
#if defined(WIN32)
/*
* We used to call DebugBreak() on Windows, but amazingly, it causes
* the MSVS 2010 debugger not to be able to recover a call stack.
*/
*((int *) NULL) = 123;
exit(3);
#elif defined(__APPLE__)
/*
* On Mac OS X, Breakpad ignores signals. Only real Mach exceptions are
* trapped.
*/
*((int *) NULL) = 123; /* To continue from here in GDB: "return" then "continue". */
raise(SIGABRT); /* In case above statement gets nixed by the optimizer. */
#else
raise(SIGABRT); /* To continue from here in GDB: "signal 0". */
#endif
}
asm { cli; };
。 - Nate Koppenhaver*((char*)-1) = 'x';
代码来引发崩溃,以便进行调试。更多细节请参阅我的答案。 - Shafik Yaghmourint *p = (int *)-1; *p = 1;
。这是因为在任何系统上都不存在地址2 ^ 64 - 1,至少现在是这样(假设指针长度为8字节)。 - user16083509