我正在尝试制作一个与不同的崩溃过程接口的Python程序(这不在我的手中).不幸的是,我正在连接的程序甚至没有可靠的崩溃!所以我想制作一个快速崩溃的C++程序,但我实际上并不知道最好和最短的方法,有谁知道我的:
int main() {
crashyCodeGoesHere();
}
Run Code Online (Sandbox Code Playgroud)
使我的C++程序可靠地崩溃
dus*_*uff 255
这个abort()功能可能是你最好的选择.它是C标准库的一部分,定义为"导致程序异常终止"(例如,致命错误或崩溃).
Mar*_*ork 113
尝试:
raise(SIGSEGV); // simulates a standard crash when access invalid memory
// ie anything that can go wrong with pointers.
Run Code Online (Sandbox Code Playgroud)
在发现:
#include <signal.h>
Run Code Online (Sandbox Code Playgroud)
Roe*_*rel 74
除以零会使应用程序崩溃:
int main()
{
return 1 / 0;
}
Run Code Online (Sandbox Code Playgroud)
Kei*_*las 64
*((unsigned int*)0) = 0xDEAD;
Run Code Online (Sandbox Code Playgroud)
sam*_*var 52
那么,我们是否堆栈溢出,或不?
for (long long int i = 0; ++i; (&i)[i] = i);
Run Code Online (Sandbox Code Playgroud)
(不保证会以任何标准崩溃,但也不是任何建议的答案,包括已经接受的答案,因为SIGABRT无论如何都可能被捕获.实际上,这将在任何地方崩溃.)
Dan*_*n F 15
assert(false); 也很不错.
根据ISO/IEC 9899:1999,当未定义NDEBUG时,保证崩溃:
如果定义了NDEBUG,则断言宏被简单地定义为
Run Code Online (Sandbox Code Playgroud)#define assert(ignore) ((void)0)断言宏根据每次包含的NDEBUG的当前状态重新定义.
[...]
断言宏将诊断测试放入程序中; [...]如果表达式(具有标量类型)是假的[...].然后它调用中止函数.
Pla*_*aHH 11
由于崩溃是调用未定义行为的一种症状,并且由于调用未定义的行为可能会导致任何事情,包括崩溃,我认为您不想真正崩溃您的程序,而只是将其放入调试器中.最便携的方式可能是abort().
虽然raise(SIGABRT)具有相同的效果,但写作肯定更多.但是,可以通过安装信号处理程序来拦截这两种方式SIGABRT.因此,根据您的情况,您可能需要/需要提出另一个信号.SIGFPE,SIGILL,SIGINT,SIGTERM或者SIGSEGV可能是要走的路,但他们都可以被截获.
当你无法移植时,你的选择可能更广泛,比如SIGBUS在linux上使用.
我唯一的闪光是abort()函数:
它通过异常程序终止来中止进程.它生成SIGABRT信号,默认情况下会导致程序终止将不成功的终止错误代码返回给主机环境.程序终止而不执行自动或静态存储持续时间对象的析构函数,并且不调用任何atexit(在程序终止之前由exit()调用)函数.它永远不会返回其调用者.
答案是特定于平台的,取决于您的目标.但是这里是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
}
Run Code Online (Sandbox Code Playgroud)
C++可以通过在处理另一个异常时抛出异常来确定性地崩溃!标准说永远不会从析构函数中抛出任何异常,或者从不在析构函数中使用任何可能抛出异常的函数.
我们必须做一个函数,所以让我们离开析构函数等.
ISO/IEC14882§15.1-7的一个例子.根据C++标准应该是崩溃.可以在此处找到Ideone示例.
struct C {
C() { }
C(const C&) {
if (std::uncaught_exceptions()) {
throw 0; // throw during copy to handler’s exception-declaration object (15.3)
}
}
};
int main() {
try {
throw C(); // calls std::terminate() if construction of the handler’s
// exception-declaration object is not elided (12.8)
} catch(C) { }
}
Run Code Online (Sandbox Code Playgroud)
ISO/IEC14882§15.1/ 9提到不带try块的throw会导致对abort的隐式调用:
如果当前没有处理异常,则执行不带操作数的throw-expression调用std :: terminate()
其他包括:从析构函数抛出:ISO/IEC14882§15.2/ 3
*( ( char* ) NULL ) = 0;
Run Code Online (Sandbox Code Playgroud)
这将产生分段错误.
通过死循环递归方法调用堆栈溢出怎么办?
#include <windows.h>
#include <stdio.h>
void main()
{
StackOverflow(0);
}
void StackOverflow(int depth)
{
char blockdata[10000];
printf("Overflow: %d\n", depth);
StackOverflow(depth+1);
}
Run Code Online (Sandbox Code Playgroud)
这在我的Linux系统上崩溃,因为字符串文字存储在只读内存中:
0[""]--;
Run Code Online (Sandbox Code Playgroud)
顺便说一句,g ++拒绝对此进行编译。编译器变得越来越聪明:)