[c++] 什麼是使C ++程序崩潰的最簡單方法?


Answers

嘗試:

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

在發現:

#include <signal.h>
Question

我正在嘗試製作一個Python程序,該程序可以與不同的崩潰程序進行交互(這不在我的手中)。 不幸的是,我接口的程序甚至不能可靠地崩潰! 所以我想製作一個故意崩潰的C ++程序,但我實際上並不知道最佳和最短的方法來做到這一點,是否有人知道我的:

int main() {
    crashyCodeGoesHere();
}

使我的C ++程序可靠地崩潰




int i = 1 / 0;

你的編譯器可能會提醒你,但是它在GCC 4.4.3下編譯得很好。這可能會導致一個SIGFPE(浮點異常),這在SIGSEGV(內存分段違規)其他答案的原因,但它仍然是一個崩潰。 在我看來,這更可讀。

另一種方法,如果我們要作弊並使用signal.h ,則是:

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

這是保證殺死子進程,以對比SIGSEGV。




*((unsigned int*)0) = 0xDEAD;



還沒有提到的一個:

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

這將把空指針作為一個函數指針,然後調用它。 就像大多數方法一樣,這不能保證程序崩潰,但是操作系統允許它不受檢查並且程序返回的機會是微不足道的。




 throw 42;

只是答案... :)




這樣做的一種時尚方式是純虛函數調用:

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編譯,打印出:

純虛擬方法稱為

終止調用沒有活動的異常

中止(核心傾棄)




C ++可以通過並行2個異常確定性地崩潰! 標准說永遠不要從析構函數中拋出任何異常,也不要在可能拋出異常的析構函數中使用任何函數。

我們必須做一個函數,讓我們離開析構函數等等。

ISO / IEC 14882§15.1-7的一個例子。 應該按照C ++標准進行崩潰。 在這裡可以找到Ideone的例子

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/ 9提到沒有嘗試塊的拋出導致隱式調用中止:

如果當前沒有異常處理,執行不帶操作數的throw-expression調用std :: terminate()

其他包括:從析構函數中拋出: ISO / IEC 14882§15.2/ 3




int* p=0;
*p=0;

這應該也會崩潰。 在Windows上,它使用AccessViolation崩潰,它應該在所有操作系統上執行相同的操作。




或者因為我們在樂隊旅行車上的另一種方式。

一塊可愛的無限遞歸。 保證吹你的堆棧。

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

打印出來:

分割故障(核心轉儲)




int *p;

嘗試去除指針p(* p = 2)然後你會崩潰。

2。

 int main()
{
  int i = 2;
int j = i/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;
  }

}

希望這崩潰。 乾杯。




雖然這個問題已經有一個被接受的答案...

void main(){
    throw 1;
}

或者... void main(){throw 1;}




這一個缺失:

int main = 42;



由於崩潰是調用未定義行為的一個症狀,並且由於調用未定義的行為可能會導致任何事情,包括崩潰,所以我認為您不希望真正崩潰程序,而只是將其放入調試器中。 最簡單的方法是abort()

雖然raise(SIGABRT)具有相同的效果,但寫作肯定更多。 然而,兩種方式都可以通過為SIGABRT安裝信號處理程序來攔截。 所以根據你的情況,你可能需要/需要提出另一個信號。 SIGFPESIGILLSIGINTSIGTERMSIGSEGV可能是要走的路,但它們都可以被攔截。

當你無法移植時,你的選擇可能會更廣泛,例如在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
}



Links



Tags

c++ c++   crash