2011-11-12 13 views
8

Il bug mi ha disturbato per due giorni: durante l'esecuzione del codice ho un errore di runtime di "termina chiamato senza un'eccezione attiva \ n Aborted ",perché?Che cosa significa il seguente errore di runtime: "termina chiamato senza un'eccezione attiva n Interrotto"

Cerco di individuare il codice e trovare la riga potrebbe essere uscire dal codice "xx = new int [num]", il numero nel mio caso di test è circa 640000 (64 MB di memoria in nuovo). quando imposto il numero molto più piccolo di 10, è OK, ma il mio codice ottiene una risposta sbagliata questa volta.

Provo a eliminare tutta la clausola "try/catch" ma ho ancora questo errore.

Anche io // tutta la funzione che chiama la clausola "xx = new int [num]", l'errore esiste ancora e questa volta trovo che il codice potrebbe uscire è un normale "ciclo for".

Tutto il caso ha superato il compilatore, non hai mai riscontrato questo errore nell'esecuzione del codice? Grazie!

I // qualche clausola di eliminazione e ottenere l'errore di seguito: * glibc rilevato * ./ESMF_RegridWeightGen: munmap_chunk(): puntatore non valido: 0x00000000005cd376 *

+1

Prova a mettere un 'provare/catch' bloccare intorno tutto il corpo' main' e vedere se ci sono delle eccezioni ... –

+0

Hai un piccolo esempio di codice che dimostra il problema? –

+0

hai più thread? – neagoegab

risposta

4

Il "terminare senza eccezione attiva" messaggio indica che, ad un certo punto del programma, la gestione delle eccezioni è stata interrotta.

L'allocazione di memoria è probabilmente la causa principale, ma probabilmente non il sito di errore. La grande allocazione genererà un'eccezione std :: bad_alloc e questa eccezione viene gestita in modo errato da qualche parte.

Per convalidare la teoria, inserire una riga come

throw std::logic_error("Foo"); 

sopra l'assegnazione, questo dovrebbe innescare il bug pure.

ho incontrato due cause più comuni per questo:

  • programmi multithread MinGW compilato senza le bandiere giuste
  • Un distruttore che è stato chiamato come parte del processo di svolgimento pila ha generato un'eccezione

Dovresti essere in grado di diagnosticare quest'ultima condizione con un debugger. Una traccia di stack della tua applicazione (ad esempio ottenuta eseguendola in gdb) dovrebbe essere di grande aiuto.

+0

che dire dell'allocazione di ~ 2,5 GB? 640000 * sizeof (int) – neagoegab

+2

@neagoegab: l'ultima volta che ho controllato, sizeof (int) <10, quindi 640,000 * sizeof (int) <6,400,000 <6,4 MB. Potrebbe essere troppo grande e potrebbe lanciare uno std :: bad_alloc. Quale dovrebbe risultare, nel peggiore dei casi, in una chiamata terminata che stampa std :: bad_alloc, non in "termina chiamata senza un'eccezione attiva". C'è un problema peggiore da qualche parte, e la sua allocazione troppo grande lo sta solo innescando. – thiton

+0

sì, hai ragione. – neagoegab

7

Ho riscontrato questo quando ho provato a usare il lancio; al di fuori di una clausola di cattura. Il rethrow fallisce e viene visualizzato quel messaggio di errore.

+0

Grazie, mi ha salvato subito. – Etherealone

18

Quando ho visto questo errore, è stato causato dalla distruzione dell'oggetto thread prima che il thread che incapsulato è stato chiuso.

+1

Potrebbe non avere nulla a che fare con il thread. Potresti avere 'std :: thread foo (...)' in un blocco locale e lanciare un'eccezione dopo aver avviato il thread. Prima che la tua eccezione venga catturata, si verifica il distruttore del thread e chiama 'std :: terminate()', il che rende difficile il debug della vera eccezione! –

1

Con MinGW, l'aggiunta dell'opzione del compilatore -mthreads a gcc risolve questo problema.

Da the gcc manual:

-mthreads

Support thread-safe la gestione delle eccezioni in Mingw32. Il codice che si basa sulla gestione delle eccezioni thread-safe deve compilare e collegare tutto il codice con l'opzione -mthreads. Durante la compilazione, -mthreads definisce -D_MT; durante il collegamento, collega in una libreria di helper per thread speciale -lmingwthrd che pulisce i dati di gestione delle eccezioni per thread.

2

Come Gearóid Murphy detto l'errore si verifica quando l'oggetto viene distrutto filo prima della funzione filo stesso è stato completamente eseguito. Ho rilevato questo errore utilizzando la libreria tinythread (http://tinythreadpp.bitsnbites.eu/):

Prima:

#include "tinythread.h" 
... 
void fork_thread(void (*function_pointer)(void * arg), void * arg_pointer) { 
    tthread::thread t(function_pointer, arg_pointer); 
    // t is destructed here, causing the "terminate called ..." error 
} 

Dopo:

#include "tinythread.h" 
... 
void fork_thread(void (*function_pointer)(void * arg), void * arg_pointer) { 
    tthread::thread * t = new tthread::thread(function_pointer, arg_pointer); 
    // now the new thread object is not destructed here, preventing 
    // the "terminate called ..." error. Remember that because thread 
    // object must now be destructed explicitly (i.e. manually) with delete 
    // call you should store the pointer t to a vector of thread pointers 
    // for example. 
}