web-dev-qa-db-ja.com

C ++プログラムをクラッシュさせる最も簡単な方法は何ですか?

私は別のクラッシュするプロセスとインターフェイスするPythonプログラムを作成しようとしています(それは手に負えません)。残念ながら、私がインターフェイスしているプログラムは確実にクラッシュしません!だから私は意図的にクラッシュする簡単なC++プログラムを作りたいが、実際にそれを行うための最良かつ最短の方法を知りません、誰も私の間に置くべきものを知っていますか?

int main() {
    crashyCodeGoesHere();
}

c ++プログラムを確実にクラッシュさせる

306
jonathan topf

abort()関数はおそらく最善の方法です。これはC標準ライブラリの一部であり、「プログラムの異常終了の原因」として定義されています(致命的なエラーやクラッシュなど)。

250
duskwuff

試してください:

raise(SIGSEGV);  // simulates a standard crash when access invalid memory
                 // ie anything that can go wrong with pointers.

で発見:

#include <signal.h>
108
Martin York

ゼロで除算すると、アプリケーションがクラッシュします。

int main()
{
    return 1 / 0;
}
74
Roee Gavirel
*((unsigned int*)0) = 0xDEAD;
64
Keith Nicholas

さて、私たちはstackoverflowですか?

for (long long int i = 0; ++i; (&i)[i] = i);

(どの標準でもクラッシュすることは保証されていませんが、SIGABRTがとにかくキャッチされた可能性があるため、受け入れられたものを含め、提案された回答もありません。実際には、これはどこでもクラッシュします。)

50
sam hocevar
 throw 42;

ちょうど答え... :)

34
Macke

assert(false);もかなり良いです。

ISO/IEC 9899:1999によると、NDEBUGが定義されていない場合にクラッシュすることが保証されています。

NDEBUGが定義されている場合[...]、assertマクロは単に

#define assert(ignore) ((void)0)

Assertマクロは、含まれるたびにNDEBUGの現在の状態に従って再定義されます。

[...]

Assertマクロは、診断テストをプログラムに入れます。 [...]式(スカラー型でなければならない)がfalse [...]の場合。次に、中止機能を呼び出します。

15
Dan F

クラッシュは未定義の動作を呼び出すことの兆候であり、未定義の動作を呼び出すとクラッシュを含む何かにつながる可能性があるため、プログラムを実際にクラッシュさせたいとは思わず、デバッガにドロップするだけです。最も移植性の高い方法は、おそらくabort()です。

raise(SIGABRT)にも同じ効果がありますが、間違いなく書くべきです。ただし、SIGABRTのシグナルハンドラをインストールすることで、両方の方法を傍受できます。そのため、状況に応じて、別の信号を発生させる必要がある場合があります。 SIGFPESIGILLSIGINTSIGTERM、またはSIGSEGVを使用する方法がありますが、それらはすべてインターセプトできます。

移植できない場合は、LinuxでSIGBUSを使用するなど、選択肢がさらに広がる可能性があります。

11
PlasmaHH

答えはプラットフォーム固有であり、目標によって異なります。しかし、ここに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
}
9
Paul Biggar

私が持っていた唯一のフラッシュはabort()function

プログラムを異常終了させて​​プロセスを中止しますSIGABRTシグナルを生成し、デフォルトでプログラムはホスト環境に失敗した終了エラーコードを返して終了します。プログラムは終了しますデストラクタの実行なし自動または静的ストレージ期間のオブジェクトの場合、および呼び出しなし any atexit(プログラムが終了する前にexit()によって呼び出される)関数呼び出し元に戻ることはありません。

9
samridhi

C++は、別の処理中に例外をスローすることにより、確定的にクラッシュする可能性があります!標準では、デストラクタから例外をスローすることはありませんORは、デストラクタで例外をスローする可能性のある関数を使用しません。

関数を作成する必要があるので、デストラクタなどを残すことができます。

ISO/IEC 14882§15.1-7の例C++標準に従ってクラッシュする必要があります。 イデオネの例はここにあります

class MyClass{
    public:
    ~MyClass() throw(int) { throw 0;}
};

int main() {
  try {
    MyClass myobj; // its destructor will cause an exception

    // This is another exception along with exception due to destructor of myobj and will cause app to terminate
     throw 1;      // It could be some function call which can result in exception.
  }
  catch(...)
  {
    std::cout<<"Exception catched"<<endl;
  }
  return 0;
}

ISO/IEC 14882§15.1/ 9tryブロックなしのthrowに言及しているため、アボートの暗黙的な呼び出しが発生します。

現在例外が処理されていない場合、オペランドなしでthrow-expressionを実行すると、std :: terminate()が呼び出されます

その他:デストラクタからのスロー:ISO/IEC 14882§15.2/ 3

7
Abhinav
*( ( char* ) NULL ) = 0;

これにより、セグメンテーション違反が発生します。

5
wrren

これはありません:

int main = 42;
5
mvds

デッドループの再帰的なメソッド呼び出しによるスタックオーバーフローはどうですか?

#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);
}

Microsoft KBの元の例 を参照してください

5
sll

これは、上記の回答で提示されたアボートのより保証されたバージョンです。sigabrtがブロックされた場合の状況を処理します。

#include<stdio.h>
#include<signal.h>
#include<unistd.h> 
#include<stdlib.h>
int main()
{
    sigset_t act;
    sigemptyset(&act);
    sigfillset(&act);
    sigprocmask(SIG_UNBLOCK,&act,NULL);
    abort();
}
4
bashrc
int i = 1 / 0;

コンパイラーはおそらくこれについて警告しますが、GCC 4.4.3では問題なくコンパイルされます。これにより、おそらく SIGFPE(浮動小数点例外)が発生します。他の回答の原因としてのSIGSEGV(メモリセグメンテーション違反)ですが、それでもクラッシュです。私の意見では、これははるかに読みやすいです。

別の方法として、チートしてsignal.hを使用する場合は、次のとおりです。

#include <signal.h>
int main() {
    raise(SIGKILL);
}

これにより、SIGSEGVとは対照的に、サブプロセスが強制終了されます。

4
AlexWebr

文字列リテラルが読み取り専用メモリに保存されているため、これは私のLinuxシステムでクラッシュします。

0[""]--;

ところで、g ++はこれをコンパイルすることを拒否します。コンパイラはますます賢くなっています:)

4
fredoverflow
int* p=0;
*p=0;

これもクラッシュするはずです。 WindowsではAccessViolationでクラッシュし、すべてのOSで同じように動作するはずです。

3
laci37

この質問にはすでに回答がありますが...

void main(){
    throw 1;
}

または... void main(){throw 1;}

2

これは、GoogleがBreakpadで提供するスニペットです。

  volatile int* a = reinterpret_cast<volatile int*>(NULL);
  *a = 1;
2
Cory Trese

システムが読み取り専用メモリブロックをサポートしていない限り、読み取り専用メモリに書き込むとセグメンテーションエラーが発生します。

int main() {
    (int&)main = 0;
}

Windows 7ではMingGW 5.3.0、Linux MintではGCCでテストしました。他のコンパイラやシステムでも同様の効果が得られると思います。

2
NO_NAME
int main(int argc, char *argv[])
{
    char *buf=NULL;buf[0]=0;
    return 0;
}
2
Aniket Inge

または、バンドワゴンに乗っているからです。

無限の再帰の素敵な作品。あなたのスタックを爆破することが保証されています。

int main(int argv, char* argc)
{
   return main(argv, argc)
}

プリントアウト:

セグメンテーションフォールト(コアダンプ)

1
Matt
int main()
{
    int *p=3;
    int s;
    while(1) {
        s=*p;
        p++;
    }
}
0
sc_cs

まだ言及されていないもの:

((void(*)())0)();

これは、nullポインターを関数ポインターとして扱い、それを呼び出します。ほとんどの方法と同様に、これはプログラムのクラッシュを保証するものではありませんが、OSがこれをチェックしないままにしてプログラムが復帰する可能性は無視できます。

0
Anton Golov

これを行うスタイリッシュな方法は、純粋な仮想関数呼び出しです。

class Base;

void func(Base*);

class Base
{
public:
   virtual void f() = 0;
   Base() 
   {
       func(this);
   }
};

class Derived : Base
{
   virtual void f()
   {
   }
};

void func(Base* p)
{
   p->f();
}


int main()
{
    Derived  d;
}

Gccでコンパイルすると、次のように出力されます。

と呼ばれる純粋な仮想メソッド

アクティブな例外なしで呼び出された終了

中止(コアダンプ)

0
void main()
{

  int *aNumber = (int*) malloc(sizeof(int));
  int j = 10;
  for(int i = 2; i <= j; ++i)
  {
      aNumber = (int*) realloc(aNumber, sizeof(int) * i);
      j += 10;
  }

}

これがクラッシュすることを願っています。乾杯。

0
senthil