2015-02-16 17 views
13

Ho una clausola catch try in cui il più esterno catch(...) non è mai successo fino ad ora. Dopo alcune modifiche, viene generata un'eccezione che non gestisco con gli altri casi. C'è un modo per ottenere almeno alcune informazioni sull'eccezione anche se la prendo con (...)?Ottieni informazioni dall'eccezione catturata con catch (...)?

catch (const cone::BeginnersLibException& ex) 
{ 
    // handle the exception 
} 
catch (const std::exception& ex) 
{ 
    // handle std exception 
} 
catch (...) 
{ 
    log("Unknown exception caught."); 
    // How can I get more information about this exception? 
} 

Edit: ecco un frammento di codice che funziona per me:

#include <cxxabi.h> 

// more code here 
} catch (...) { 
    std::string exName(abi::__cxa_current_exception_type()->name()); 
    std::cout<<"unknown exception: "<< exName <<std::endl; 
    throw; 
} 
+0

Se un'eccezione deriva da 'std :: exception', puoi chiamare' catch (const std :: exception & exc) 'e quindi usare' exc.what() ' – Mints97

+1

@ Mints97: sicuro, ma quello non è l'OP situazione. –

+0

Manca uno snippet di codice – Niall

risposta

15

È possibile farlo utilizzando gdb o in un altro debugger. Dì al debugger di fermarsi quando viene lanciata un'eccezione (in gdb il comando è esilarante catch throw). Quindi vedrai non solo il tipo di eccezione, ma da dove proviene esattamente.

Un'altra idea è di commentare lo catch (...) e lasciare che il runtime termini l'applicazione e sperare di dirti di più sull'eccezione.

Una volta individuata l'eccezione, è necessario provare a sostituirla o aumentarla con qualcosa che deriva da std::exception. Dover dare uno catch (...) non è grandioso.

Se si utilizza GCC o Clang, è anche possibile provare __cxa_current_exception_type()->name() per ottenere il nome del tipo di eccezione corrente.

+1

Ho dovuto includere cxxabi. h – Beginner

+1

+1 per '__cxa_current_exception_type() -> nome()'. Poiché non esiste supporto linguistico per ispezionare l'eccezione, le estensioni specifiche del fornitore e della piattaforma sono un modo pragmatico per andare. – mskfisher

+0

Si prega di ripubblicare questa risposta su https://stackoverflow.com/questions/1055299/is-there-any-way-to-get-some-information-at-least-for-catch; questo è il stessa domanda, ma la tua risposta offre opzioni che non sono visibili lì. – zwol

5

Come variante su suggerimento di Giovanni Zwinck per commentare il blocco catch(...) di lasciare che il runtime terminare l'applicazione e, auspicabilmente, fornire alcune ulteriori informazioni, si potrebbe

catch (...) 
{ 
    log("Unknown exception caught in [sensible info here]; will rethrow it"); 
    throw; 
} 

allora si avrà almeno sapere dove nel il tuo programma si è verificato l'errore (se ci sono diverse possibilità).

2

Una possibilità, almeno su Windows, è scrivere un minidump utilizzando MiniDumpWriteDump per ottenere l'eccezione più tracce di stack, memoria e molte informazioni utili per il debug.

2

È possibile utilizzare un debugger e abilitare l'interruzione al lancio, assumendo che le eccezioni siano davvero eccezionali, questo è un buon modo per sapere da dove proviene.

Anche una parola di avvertimento se si dovesse mai usare il fermo (...) su Windows. Con certe opzioni di compilazione questo catturerà le eccezioni SEH, questi sono i tipi di cose che non dovresti mai tentare come leggere o scrivere la memoria fuori limite.

2

L'unico modo nel codice (vale a dire non utilizzare un debugger) per ottenere informazioni da un'eccezione in un blocco catch(...) consiste nel rifondare l'eccezione e catturarla con clausole specifiche.

Ad esempio.

try 
{ 
    // code that might throw something 
} 
catch (...) 
{ 
    try_to_interpret_exception(); 
} 

void try_to_interpret_exception() // we assume an exception is active 
{ 
    try 
    { 
     throw; // rethrow the exception. Calls terminate() if no exception active 
    } 
    catch (std::exception &) 
    { 
     // handle all exception types derived from std::exception 
     // this covers all exceptions that might be thrown by 
     // the standard C++ library 
    } 
    catch (specific_exception &e1) 
    { 
     // handle all exception types derived from specific_exception 
    } 
    catch (another_specific_exception &e2) 
    { 
     // etc 
    } 
} 

Il fermo (si fa per dire) di questo approccio è che richiede al programmatore di avere una certa conoscenza di ciò che l'eccezione potrebbe essere (ad esempio da documentazione di una libreria di terze parti). |

+0

Il problema è che l'eccezione proviene da una delle librerie e non so cosa catturare. – Beginner

+0

L'unica vera soluzione è quindi esaminare la documentazione (o il codice sorgente se ce l'hai) per le librerie. Elimina una libreria alla volta dal tuo programma finché non trovi la libreria incriminata, se necessario. In realtà, tuttavia, questa situazione sarebbe stata meglio evitata (ad es. Valutando accuratamente una libreria prima di incorporarla in un programma di produzione). Non documentare le eccezioni generate è una forma davvero scarsa dal venditore della biblioteca. – Rob

+0

Minpic nitpic: vuoi passare dal tipo di eccezione più specifico a quello generico, non viceversa. Alcune gerarchie di eccezioni derivano da 'std :: exception', o' std :: runtime_error' (dato che qui entra in gioco '.what()'). Se lo prendi per primo, potresti prendere più di quello che hai indignato. – DevSolar

Problemi correlati