Qual è il modo più semplice per arrestare un programma C ++?


318

Sto cercando di creare un programma Python che si interfaccia con un diverso processo anomalo (che è fuori dalle mie mani). Sfortunatamente il programma con cui mi sto interfaccia non si blocca nemmeno in modo affidabile! Quindi voglio creare un programma C ++ rapido che si blocchi di proposito ma in realtà non conosco il modo migliore e più breve per farlo, qualcuno sa cosa mettere tra i miei:

int main() {
    crashyCodeGoesHere();
}

per rendere affidabile il mio programma C ++ in modo affidabile


4
puoi usare l'assemblaggio in linea per tentare di eseguire le istruzioni private:asm { cli; };
Nate Koppenhaver,

@aitchnyu Penso che ci sia una differenza nell'usabilità delle risposte ad ogni domanda. (FYI: Non ho votato nulla per nessuna delle due domande)
Andrew Barber,

qualche commento sul lancio dell'eccezione mentre uno si sta già propugnando ?? per favore chk la mia risposta sotto anc comment
Abhinav

4
Redis utilizza il seguente *((char*)-1) = 'x';codice per indurre un arresto anomalo al fine di eseguire il debug leggi di più nella mia risposta qui
Shafik Yaghmour,

Ho trovato questa domanda alla ricerca di un caso di test per un sistema di segnalazione degli arresti anomali. Avevo bisogno di forzare un arresto anomalo durante il normale runtime per invocare il reporter di arresto anomalo e l'invio di dump dello stack. Grazie!
Cory Trese,

Risposte:


264

La abort()funzione è probabilmente la soluzione migliore. Fa parte della libreria standard C ed è definito come "causa della chiusura anomala del programma" (ad esempio, un errore irreversibile o un arresto anomalo).


14
Si noti che un crash through abort()non chiama alcun distruttore o atexitfunzione, anche se probabilmente non avrà importanza qui.
Xeo,

139
@Xeo: Se avesse chiamato distruttori e atexits, non sarebbe un incidente adesso?
Donal Fellows,

Poiché abort()è la risposta corretta, allora 'exit (-1); `dovrebbe essere accettabile?
asir6,

9
No, poiché non provoca un arresto anomalo, segnala semplicemente che non è stato possibile eseguire alcuna operazione.
Boatcoder

Finestre. GCC-5.4.0. Codice di uscita: 3. Nessuna finestra di messaggio di errore. Messaggio della console: "Questa applicazione ha richiesto a Runtime di terminarlo in modo insolito. Per ulteriori informazioni, contattare il team di supporto dell'applicazione.".
Vadzim,

113

Provare:

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

Trovato in:

#include <signal.h>

3
È molto più che definito dall'implementazione: il segnale può essere catturato signal(). La maggior parte delle applicazioni sane non lo fanno, però.
duskwuff -inattivo-

12
Si bloccherà esattamente allo stesso modo di un normale SIGSEGV all'interno dell'applicazione (che è il modo in cui si blocca la maggior parte delle applicazioni). È ben definito ciò che fa (per impostazione predefinita esce dall'applicazione e genera un file core). Sì, puoi impostare un gestore, ma se ne hai uno non vuoi testarlo allo stesso modo !!
Martin York,

1
+1 per raise(). Ciò ti consente di testare diversi tipi di eccezioni semplicemente modificando l'argomento.

3
soluzione preferita, tuttavia dipende dalla piattaforma.
Nadim Farhat,

@NadimFarhat: in che modo. Un segnale è un segnale su tutte le piattaforme.
Martin York,

74

La divisione per zero causerà l'arresto anomalo dell'applicazione:

int main()
{
    return 1 / 0;
}

29
A seconda di quanto sia intelligente il tuo compilatore, questo verrà rilevato al momento della compilazione. So che Visual Studio 2008 non lo compilerà per c ++ o c #.
Aidan,

2
L'ho compilato ed eseguito, vuoi che ti cartei il file .exe?
Roee Gavirel,

1
Nella configurazione di rilascio nelle versioni recenti di Visual Studio come 2010, verrà eseguito senza problemi. Immagino sia un po 'di ottimizzazione.
tedyyu,

2
in ogni caso non si schianta sul braccio
Sherpya,

2
Questo è un comportamento indefinito e non è garantito l'arresto anomalo. Spesso i compilatori ritengono che il comportamento indefinito sia irraggiungibile. Ciò può comportare la maincancellazione totale del corpo, comprese le retistruzioni. L'esecuzione potrebbe rientrare nella seguente funzione.
usr

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

54
Questo non è garantito per crash.
Programmatore di Windows,

8
@Windowsprogrammer: no, non è garantito . Ma quale sistema operativo sano non ferma un'applicazione che tenta di accedere alla memoria all'indirizzo 0?
Joachim Sauer,

29
"Ma quale sistema operativo sano non ferma un'applicazione che tenta di accedere alla memoria all'indirizzo 0?" - Non è proprio quello che vuoi chiedere, ma risponderò comunque. In alcuni computer è presente la RAM all'indirizzo 0, ed è perfettamente significativo che un programma memorizzi un valore lì. Una domanda più significativa sarebbe "Quale sistema operativo non blocca un'applicazione che accede alla memoria all'indirizzo che un'implementazione C ++ ha riservato per un puntatore null?" In quel caso non ne conosco nessuno. Ma il programma originale riguarda il linguaggio C ++ e non i sistemi operativi.
Programmatore di Windows,

6
Il suo comportamento indefinito. È perfettamente OK che questo non faccia nulla. Una macchina che non si arresta in modo anomalo: tutto ciò che esegue un processore serie Z80 (suppongo (la mia Z80a non fa nulla)).
Martin York,

28
Anche se questo non è garantito per crash, è uno dei tipi più comuni di crash in C ++. Quindi, se vuoi simulare un incidente, questo è un modo "autentico" per farlo :)
Chris Burt-Brown,

53

Bene, siamo in overflow dello stack o no?

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

(Non è garantito il crash di alcuno standard, ma nessuna delle risposte suggerite, inclusa quella accettata, SIGABRTpotrebbe essere stata catturata comunque. In pratica, si bloccherà ovunque.)


4
Vedo che essere divertente su un sistema con pagine di codice non protette e si sovrascrive il programma con del codice che è accidentalmente un ciclo infinito che non fa nulla. Altamente altamente altamente altamente improbabile ma potenzialmente possibile.
Martin York,

@Loki: E se leggesse da ogni 4000th byte? Sarebbe meno probabile che si schiantasse? Decisamente meno pericoloso.
Mooing Duck,

70
Quell'algoritmo di crash non è O (1)!
Anton Barkovsky,

@MooingDuck: sto solo facendo un commento divertente. Non prenderlo sul serio :-) Ma sarebbe interessante se qualcuno trovasse una sequenza di istruzioni che ha fatto qualcosa di divertente.
Martin York,

1
@LokiAstari: hai assolutamente ragione. Stavo pensando (&i)[i] += !iinvece, ma temevo che il compilatore potesse essere abbastanza intelligente e volerlo ottimizzare. :-)
sam hocevar,

35
 throw 42;

Solo la risposta ... :)


1
Finestre. GCC-5.4.0. Codice di uscita: 3. Nessuna finestra di messaggio di errore. Messaggio console: "termina chiamato dopo aver lanciato un'istanza di 'int' Questa applicazione ha richiesto a Runtime di terminarlo in modo insolito. Per ulteriori informazioni, contattare il team di supporto dell'applicazione.".
Vadzim,

15

assert(false); è anche abbastanza buono.

Secondo ISO / IEC 9899: 1999 è garantito un arresto anomalo quando NDEBUG non è definito:

Se NDEBUG è definito [...] la macro assert è definita semplicemente come

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

La macro assert viene ridefinita in base allo stato corrente di NDEBUG ogni volta che viene inclusa.

[...]

La macro assert inserisce test diagnostici nei programmi; [...] se espressione (che deve avere un tipo scalare) è falsa [...]. Quindi chiama la funzione di interruzione.


Ricordo vagamente che VC 2005 si comportava diversamente tra debug e rilascio con assert?
Tom Kerr,

8
@ Tom assertè reso equivalente a ((void)0)in modalità Rilascio.
Seth Carnegie,

2
@SethCarnegie Non vedi cosa c'è di sbagliato in questo - solo se la volontà definita da NDEBUG non è in crash? La risposta di Dans è stata abbastanza giusta IMHO.
Adrian Cornish,

@AdrianCornish Stavo solo rispondendo alla domanda di Tom Kerr, senza dire che questa risposta era sbagliata. Non ho votato in negativo questa risposta.
Seth Carnegie,

3
Non so perché dovrebbe creare una versione "release" di questo codice di prova.
Gioele B,

11

Poiché un arresto anomalo è un sintomo dell'invocazione di comportamenti indefiniti, e poiché l'invocazione di comportamenti indefiniti può portare a qualsiasi cosa, incluso un arresto anomalo, non penso che tu voglia davvero interrompere il tuo programma, ma fallo cadere in un debugger. Il modo più portatile per farlo è probabilmenteabort() .

Mentre raise(SIGABRT)ha lo stesso effetto, è sicuramente più da scrivere. Entrambi i modi possono tuttavia essere intercettati installando un gestore di segnale per SIGABRT. Pertanto, a seconda della situazione, potrebbe essere necessario / necessario aumentare un altro segnale. SIGFPE, SIGILL, SIGINT, SIGTERMO SIGSEGVpotrebbe essere la strada da percorrere, ma tutti possono essere intercettati.

Quando puoi essere insostituibile, le tue scelte potrebbero essere anche più ampie, come usare SIGBUSsu Linux.


1
Dubito davvero che voglia coinvolgere un debugger. Sembra voler testare cosa succede quando il chiamante di un programma che si blocca riceve un incidente. È molto ragionevole.
Donal Fellows,

9

L'unico flash che ho avuto è la funzione abort () :

Interrompe il processo con un'interruzione anomala del programma e genera il segnale SIGABRT , che per impostazione predefinita provoca la chiusura del programma restituendo un codice di errore di interruzione non riuscito nell'ambiente host. Il programma viene terminato senza eseguire distruttori per oggetti con durata di memorizzazione automatica o statica e senza chiamare alcuna funzione atexit (che viene chiamata da exit () prima che il programma termini). Non torna mai al suo chiamante.


9

La risposta è specifica per la piattaforma e dipende dai tuoi obiettivi. Ma ecco la funzione di crash di Mozilla Javascript, che a mio avviso illustra molte delle sfide per far funzionare questo:

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
}

2
Dovresti lasciar perdere e usare invece jQuery.
Thomas Weller,

1
Questo è un comportamento indefinito e non è garantito l'arresto anomalo. Spesso i compilatori ritengono che il comportamento indefinito sia irraggiungibile. In quel caso almeno la linea che si blocca verrà eliminata e potrebbe esserlo anche altro codice.
usr

8

Vedo che ci sono molte risposte pubblicate qui che cadranno in casi fortunati per portare a termine il lavoro, ma nessuna di esse è deterministica al 100% per il crash. Alcuni si arresteranno in modo anomalo su un hardware e sistema operativo, altri no. Tuttavia, esiste un modo standard secondo lo standard C ++ ufficiale per farlo arrestare.

Citando dalla norma C ++ ISO / IEC 14882 §15.1-7 :

Se il meccanismo di gestione delle eccezioni, dopo aver completato l'inizializzazione dell'oggetto dell'eccezione ma prima dell'attivazione di un gestore per l'eccezione, chiama una funzione che esce tramite un'eccezione, viene chiamato std :: terminate (15.5.1).

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) { }
}

Ho scritto un piccolo codice per dimostrarlo e può essere trovato e provato su Ideone qui .

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

Le menzioni ISO / IEC 14882 §15.1 / 9 lanciano senza provare il blocco con conseguente chiamata implicita ad interrompere:

Se al momento non viene gestita alcuna eccezione, l'esecuzione di un'espressione di lancio senza operando chiama std :: terminate ()

Altri includono: lancio dal distruttore: ISO / IEC 14882 §15.2 / 3


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

Ciò produrrà un errore di segmentazione.


10
Questo non è garantito per crash.
Programmatore di Windows,

23
"Cosa succederà invece?" - Potrebbe succedere di tutto. Il comportamento non è definito, pertanto l'implementazione potrebbe assegnare 0 a una delle variabili del programma oppure assegnare 42 a una delle variabili del programma oppure formattare il disco rigido e continuare l'esecuzione del programma.
Programmatore di Windows,

7
(continuando a pensare al "programmatore di Windows") Può far esplodere il tuo computer, o può far sì che diventi vivo e conquisti l'umanità. o ... andrà in crash nel 99,9% ed è definito come "comportamento indefinito" perché nessuno vuole assumersi la responsabilità.
Roee Gavirel,

1
In realtà, non è garantito nemmeno un comportamento indefinito: potrebbe essere completamente definito e funzionare correttamente. Considera questo codice: pastebin.com/WXCtTiDD (testato su Linux come root, potresti farlo anche come utente non root se fai delle modifiche alla configurazione wiki.debian.org/mmap_min_addr )
cha0site

2
@ cha0site: lo Standard garantisce che il comportamento non sia definito, in quanto dereferenziando un puntatore nullo. Qualunque comportamento osservato su Linux è ammesso sotto l'egida del "comportamento indefinito"
Ben Voigt,

6

Questo manca:

int main = 42;

1
Sì lo fa; ma fa qualcosa di spettacolare quando lo esegui.
Joshua,

5

Che dire dello overflow dello stack tramite una chiamata al metodo ricorsivo dead loop?

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

Vedi esempio originale su Microsoft KB


4
Cosa impedirebbe a un compilatore sufficientemente intelligente di ottimizzare sia l'allocazione dello stack inutilizzata che la chiamata in coda?
JB.

@JB: sfortunatamente non ne ho idea perché non ha familiarità con la logica di ottimizzazione dei compilatori esistente
sll

8
Bene, compilato qui con gcc 4.6.0 a livelli di ottimizzazione -O2 e superiori, ottimizza perfettamente. Ha bisogno di -O1 o inferiore a segfault.
JB.

@Abhinav: pubblica la tua risposta con tutti questi modi espressi come esempi in C ++ :)
sll

5

Questo si arresta in modo anomalo sul mio sistema Linux, perché i valori letterali delle stringhe sono memorizzati nella memoria di sola lettura:

0[""]--;

A proposito, g ++ rifiuta di compilare questo. I compilatori stanno diventando sempre più intelligenti :)


4
int i = 1 / 0;

Il compilatore probabilmente ti avvertirà di questo, ma si compila bene sotto GCC 4.4.3 Questo probabilmente causerà un SIGFPE (eccezione in virgola mobile), che forse non è così probabile in un'applicazione reale come SIGSEGV (violazione della segmentazione della memoria) come le altre risposte causano, ma è ancora un incidente. Secondo me, questo è molto più leggibile.

Un altro modo, se vogliamo imbrogliare e usare signal.h, è:

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

Questo è garantito per uccidere il sottoprocesso, in contrasto con SIGSEGV.


2
Questo non è garantito per crash.
Programmatore di Windows,

11
Il linguaggio C ++ non garantisce che 1/0 provocherà un SIGFPE. Il comportamento non è definito. L'implementazione potrebbe dire che il risultato è 42.
Programmatore di Windows

1
Quando il comportamento non è definito, l'implementazione può fare quello che vuole. Il linguaggio C ++ non impedisce né richiede un'implementazione per scrivere un dump di arresto anomalo, il linguaggio C ++ non impedisce né richiede un'implementazione per assegnare 42, ecc.
Programmatore di Windows

2
@Giorgio se l'hardware non ha alcun modo di intrappolarlo automaticamente costringi comunque i compilatori ad emettere almeno due istruzioni, una delle quali sarebbe anche una diramazione. Questo è circa il raddoppio del costo di una divisione. Tutti pagano così. Se è facoltativo e lo desideri, puoi sempre utilizzare una funzione di libreria per farlo ancora. Se non è facoltativo e non lo vuoi, finiresti comunque per pagare il costo.
Flexo

2
@Giorgio: ho un'applicazione che fa 100.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000 dal dal dall'es ... So per certo che 0 di questi saranno una divisione per zero, anche se il compilatore non può saperlo. Non voglio assolutamente che il compilatore installi il controllo per una divisione per zero.
Martin York,

4

Questa è una versione più sicura di abort presentata nelle risposte sopra. Si occupa della situazione in cui sigabrt è bloccato. È possibile infatti utilizzare qualsiasi segnale anziché interrompere che ha l'azione predefinita di crash del programma.

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

3
int* p=0;
*p=0;

Anche questo dovrebbe andare in crash. Su Windows si arresta in modo anomalo con AccessViolation e dovrebbe fare lo stesso su tutti i sistemi operativi che immagino.


5
on all OS-esNo, non va in crash in OS non protetti (ad esempio MS-DOS.) In realtà, a volte c'è qualcosa in indirizzo 0! Per la modalità reale x86, Interrupt Vector Table è nell'indirizzo 0.
ikh

Non si è schiantato su Irix. Mi sono purtroppo reso conto quando abbiamo portato quel codice su Linux (dove non abbiamo nemmeno raggiunto main().
Scheff

3

Questo è lo snippet fornito da Google in Breakpad.

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

1
Dal momento che sto testando Breakpad questo è esattamente quello che volevo! Ho scoperto che alcuni minidump di Breakpad non producono una traccia dello stack che punta alla riga nel mio codice che causa l'arresto anomalo. Questo lo fa, quindi posso usarlo come un buon test poc.
BuvinJ,

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

2

Sebbene questa domanda abbia già una risposta accettata ...

void main(){
    throw 1;
}

O... void main(){throw 1;}


2

La scrittura su una memoria di sola lettura provocherà un errore di segmentazione a meno che il sistema non supporti i blocchi di memoria di sola lettura.

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

L'ho provato con MingGW 5.3.0 su Windows 7 e GCC su Linux Mint. Suppongo che altri compilatori e sistemi daranno un effetto simile.


1

O in un altro modo da quando siamo sul carro della band.

Un bel pezzo di ricorsione infinita. Garantito per far saltare il tuo stack.

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

Stampa:

Errore di segmentazione (core scaricato)


13
Chiamarsi mainè in realtà un comportamento indefinito, nel caso in cui non lo sapessi :) Inoltre, la ricorsione della coda non è garantita per far saltare il tuo stack. Se vuoi una "garanzia", ​​devi fare qualcosa dopo la chiamata ricorsiva, altrimenti il ​​compilatore potrebbe ottimizzare la ricorsione in un ciclo infinito.
Fredoverflow,

0

Uno che non è stato ancora menzionato:

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

Questo tratterà il puntatore null come un puntatore a funzione e quindi lo chiamerà. Proprio come la maggior parte dei metodi, questo non è garantito per bloccare il programma, ma le possibilità che il sistema operativo permetta che ciò non venga controllato e che il programma che ritorna mai sono trascurabili.


3
Conosco diverse macchine che questo causerà un riavvio poiché il codice di avvio del sistema operativo è effettivamente mappato all'indirizzo 0. Non dare per scontato che tutto funzioni come il tuo PC. Si potrebbe dire che si è verificato un arresto anomalo, ma non è molto utile in quanto non è possibile eseguire il debug poiché tutto lo stato viene cancellato all'avvio.
Martin York,

@Loki Astari: nondimeno dirò che si tratta di un arresto anomalo: se ciò può causare, anche il programma in fase di debug potrebbe significare che è un test altrettanto valido di qualsiasi altro. D'altra parte, sono curioso di sapere quale di queste macchine può eseguire Python.
Anton Golov,

Penso che tu abbia perso il punto. Ho visto il codice OS a 0. Non significa che non ci sono sistemi con un buon codice normale da eseguire che funzionerà bene a 0. O i byte a 0 potrebbero essere altrettanto facilmente il codice operativo per il ritorno.
Martin York,

Sono a conoscenza del codice OS a 0; questo è uno dei motivi per cui dubito fortemente che i byte a 0 sarebbero il codice operativo per la restituzione. Il programma chiaramente non si sta più eseguendo, e non è uscito nel solito modo, ovvero è andato in crash - se questo non è abbastanza buono per chi lo chiede, mi aspetto che lo commenti da solo.
Anton Golov,

2
Sei a conoscenza del codice OS solo per il tuo computer. Quello che sto cercando di dire è che potrebbe fallire per te. Ma questo non significa niente. Ci sono molti sistemi là fuori. Sono sicuro che alcuni di questi potrebbero funzionare (ad es. Come non in crash). Affidarsi a comportamenti specifici di macchine / sistemi operativi è una cattiva idea e causa problemi di manutenzione a lungo termine. L'idea del sito è quella di promuovere un buon codice (non solo codificare quel tipo di opere).
Martin York,

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

}

Spero che questo si blocchi. Saluti.


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

2
Sarebbe bello avere qualche chiarimento :)
olyv,

1
il puntatore p andrà oltre lo spazio degli indirizzi del programma, il che rappresenterà un errore di memoria, poiché un processo non può accedere alla memoria di un altro processo. Ciò comporterà l'arresto anomalo del programma. il puntatore p punta a una posizione casuale nel suo spazio degli indirizzi, se viene incrementato e sottoposto a dereferenziazione all'infinito ad un certo punto, punterà allo spazio degli indirizzi di un altro programma (processo). quindi si bloccherà dopo qualche tempo.
sc_cs,

Oppure, ipoteticamente, potrebbe raggiungere un overflow di numeri interi e avvolgersi, andando avanti all'infinito. Proverei a usare long longo size_te iniziare con pil rispettivo valore massimo, o vicino ad esso, per andare in crash più velocemente. Anche se in quel caso non è ancora garantito il crash.
Patrick Roberts,

0

Un modo elegante per farlo è una pura chiamata di funzione virtuale:

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

Compilato con gcc, questo stampa:

metodo virtuale puro chiamato

termina chiamato senza un'eccezione attiva

Interrotto (core scaricato)


0

Puoi usare assembly nel tuo c ++ code MA INT 3 è solo per sistemi x86, altri sistemi potrebbero avere altre istruzioni trap / breakpoint.

int main()
{
    __asm int 3;

    return 0;
}

INT 3 provoca un interrupt e chiama un vettore di interrupt impostato dal sistema operativo.


0

Utilizzare __builtin_trap () in GCC o clang o __debugbreak () in MSVC. La mancata gestione di questi punti di interruzione / trappole comporterà un'eccezione / arresto del punto di interruzione non gestita. Altri suggerimenti che usano abort () o exit (): quelli possono essere gestiti da altri thread, rendendo più difficile vedere lo stack del thread che ha propagato il crash.


-2
char*freeThis;
free(freeThis);

Liberare un puntatore non inizializzato è un comportamento indefinito. Su molte piattaforme / compilatori, freeThisavrà un valore casuale (qualunque cosa fosse prima in quella posizione di memoria). Liberarlo chiederà al sistema di liberare la memoria a quell'indirizzo, che di solito causerà un errore di segmentazione e causerà il crash del programma.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.