Seite 1 von 1
Richtiges Exceptionhandling
Verfasst: 19. Mai 2011 14:34
von rubikon
Moin.
Wie behandele ich Exceptions richtig?
Wenn ich das z.B. in einer Methode mache:
try
{
qDebug() << "try 01";
int *a = 0;
*a = 1;
qDebug() << "try 02";
}
catch (...)
{
qDebug() << "exception";
}
qDebug() << "nach try catch";
sehe ich in der Ausgabe nur 'try 01'. Das heißt ich komme nicht in den catch Block und der restlich Code meiner Methode wird nicht ausgeführt.
Wie gehts richtig?
Verfasst: 19. Mai 2011 17:35
von woody
dein Programm stürzt ja ab. Du weißt einem NULL-pointer einen wert zu.
Verfasst: 19. Mai 2011 18:18
von franzf
SegFaults werden nicht per Exception geworfen, die runtime bricht das Programm sofort ab. Was du machen kannst, wären assertions für den debug-build (dein Programm muss dann natürlich auch getestet werden).
Verfasst: 20. Mai 2011 08:31
von odt
Wie Franz bereits erwähnte, werden in C einige "kritische" Ausnahmesituationen nicht via Exception behandelt. Via
signal kannst Du eine Funktion setzen, die bei einem Fehler aufgerufen wird. Und wenn Du von dort eine Exception wirfst...
Ich habe momentan keine Zeit um ein kleines Beispiel zusammenzustellen, lege Dir aber den relevanten Codeauszug aus meinem Projekt bei. Vielleicht bringt er Dich einen Schritt weiter. Ohne Garantie auf Portablität, Korrektheit etc etc.
Viele Grüsse, Reto
Code: Alles auswählen
#include "Exception.h"
#include "OdtCore.h"
#include <signal.h>
#include <new>
#include <cstdlib>
#ifdef Q_OS_WIN
#else
#endif
namespace OdtCore
{
class OutOfMemoryException : public Exception, public std::bad_alloc
{
public:
OutOfMemoryException();
virtual ~OutOfMemoryException() throw();
};
OutOfMemoryException::OutOfMemoryException()
:Exception( "out of memory" ){
}
OutOfMemoryException::~OutOfMemoryException() throw(){
}
OutOfMemoryException* outOfMemoryException = null;
void throwOutOfMemoryFunction() {
qDebug() << "throwOutOfMemoryFunction";
throw *outOfMemoryException;
}
void throwSignalException( int w ){
qDebug() << "throwSignalException" << w;
switch( w ){
case SIGABRT:
throw Exception( "Signal Abort: Abnormal termination, such as is initiated by the abort function." );
case SIGFPE:
throw Exception( "Signal Floating-Point Exception: Erroneous arithmetic operation, such as zero divide or an operation resulting in overflow (not necessarily with a floating-point operation)." );
case SIGILL:
throw Exception( "Signal Illegal Instruction: Invalid function image, such as an illegal instruction. This is generally due to a corruption in the code or to an attempt to execute data." );
case SIGINT:
throw Exception( "Signal Interrupt: Interactive attention signal. Generally generated by the application user." );
case SIGSEGV:
throw Exception( "Signal Segmentation Violation: Invalid access to storage: When a program tries to read or write outside the memory it is allocated for it." );
case SIGTERM:
throw Exception( "Signal Terminate: Termination request sent to program." );
default:
throw Exception( QString( "Signal Unhandled: " ) + QString::number( w ) );
}
}
void Exception::Initialize(){
Q_ASSERT( outOfMemoryException == null );
outOfMemoryException = new OutOfMemoryException();
std::set_new_handler( throwOutOfMemoryFunction );
// signal( SIGABRT , throwSignalException );
signal( SIGFPE , throwSignalException );
signal( SIGILL , throwSignalException );
signal( SIGINT , throwSignalException );
signal( SIGSEGV , throwSignalException );
// signal( SIGTERM , throwSignalException );
}
void Exception::Finalize(){
Q_ASSERT( outOfMemoryException != null );
delete outOfMemoryException;
outOfMemoryException = null;
}
Exception::Exception( const QString& message )
:_message( message ), _cause( null ){
// qDebug() << "Exception" << message;
}
Exception::Exception( const QString& message, const Exception& cause )
:_message( message ), _cause( null ){
// qDebug() << "Exception" << message << cause.message();
_cause = cause.clone();
// qDebug() << this;
// qDebug() << *this;
// qDebug() << "cause: " << cause;
}
Exception::~Exception(){
// qDebug() << "~Exception" << message() << _cause;
if( _cause != null ){
delete _cause;
_cause = null;
}
}
Exception* Exception::clone() const{
Exception* ex = new Exception( _message );
if( _cause != null ){
ex->_cause = _cause->clone();
}
return ex;
}
}
QDebug operator<<( QDebug dbg, const OdtCore::Exception& ex ){
dbg.space() << "Exception" << ex.message();
const OdtCore::Exception* cause = ex.cause();
while( cause != null ){
dbg.space() << " " << cause->message();
cause = cause->cause();
}
return dbg.space();
}