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




15 Answers

abort()函數可能是您最好的選擇。 它是C標準庫的一部分,被定義為“導致程序異常終止”(例如,致命錯誤或崩潰)。

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

int main() {
    crashyCodeGoesHere();
}

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




除以零會使應用程序崩潰:

int main()
{
    int i = 1 / 0;
}



那麼,我們在堆棧 溢出 ,還是不是?

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

(不能保證以任何標准進行崩潰,但既然SIGABRT可以被捕獲,也不會有任何建議的答案,包括已被接受的答案,實際上,這將在任何地方崩潰。)




assert(false); 也很不錯。

根據ISO / IEC 9899:1999,當NDEBUG未定義時,它將保證崩潰:

如果定義了NDEBUG,assert宏的定義簡單如下

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

每次包含時,根據NDEBUG的當前狀態重新定義斷言宏。

[...]

斷言宏將診斷測試放入程序中; [...]如果表達式(應該是標量類型)是錯誤的。 然後它調用中止函數。




我唯一的flash是abort()函數

它會終止進程並產生異常程序終止。它會生成SIGABRT信號 ,該信號默認會導致程序終止向主機環境返回一個不成功的終止錯誤代碼。終止程序時不會執行自動或靜態存儲持續時間對象的析構函數 ,並且不調用任何atexit (在程序終止之前由exit()調用)函數。 它永遠不會返回給它的調用者。




如何通過死循環遞歸方法調用堆棧溢出?

#include <windows.h>
#include <stdio.h>

void main()
{
    (0);
}

void (int depth)
{
    char blockdata[10000];
    printf("Overflow: %d\n", depth);
    (depth+1);
}

請參閱Microsoft知識庫中的原始示例




*( ( char* ) NULL ) = 0;

這會產生分段錯誤。




這是在上面的答案中提出的放棄的更有保證的版本。它處理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();
}



這在我的Linux系統上崩潰,因為字符串文字存儲在只讀內存中:

0[""]--;

順便說一句,g ++拒絕編譯這個。 編譯器變得更聰明更聰明:)




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



這是Google在Breakpad中提供的片段。

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



寫入只讀內存將導致分段錯誤,除非系統不支持只讀內存塊。

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

我已經在Windows 7上使用MingGW 5.3.0和Linux Mint上的GCC進行了測試。 我想其他編譯器和系統也會產生類似的效果。




很短,它崩潰!

int
main() {
  main();
}



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



當我們嘗試使用NULL指針訪問對象的方法時,我們的程序崩潰了。

這是一個訪問帶有無效指針的對象的典型示例。

使用namespace std;

class A 
{
int value;
public:
void dumb() const {cout << "dumb()\n";}
void set(int x) {cout << "set()\n"; value=x;}
int get() const {cout << "get()\n"; return value;}
};

int main()
{
A *pA1 = new A;
A *pA2 = NULL;
pA1->dumb();
pA1->set(10);
pA1->get();
pA2->dumb();
pA2->set(20);
pA2->get();
return 0;
}

運行輸出:

啞()

組()

得到()

啞()

組()

我們有三個A類成員函數,“dumb()”,“set()”和“get()”。 指向A對象的指針調用A的方法。使用正確分配的指針pA1調用這些方法沒有任何問題。 但是,該代碼在該行崩潰:

pA2->設置(20);

為什麼? 在該行中,為一個NULL pA2調用“set(20)”,當我們嘗試訪問A類的成員變量時崩潰,而用與A對象相同的NULL指針調用“dumb()”時沒有問題。

用非法對象指針調用方法與將非法指針傳遞給函數相同。 在調用的方法中訪問任何成員變量時會發生崩潰。 換句話說,“set(20)”嘗試訪問成員變量“value”,但“dumb()”方法不會。

如果指針是一個懸掛指針(指向已被釋放的內存),或指向當前堆棧或堆邊界之外的內存位置,則指的是程序當前未擁有的內存。 而使用這樣的指針通常會導致程序崩潰。




Related

c++ crash

Tags

c++   crash