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