Навеяно топиком "Ловля SIGSEGV через try/catch" Иногда случаются ситуации, когда приходится пользовать нестабильно работающие компоненты, код которых нельзя изменить (например third-party ActiveX компоненты или плагины). Для отлова падений в этих компонетах можно использовать SEH под Windows (что это такое неплохо описано
у Рихтера) и sigaction/siglongjmp под UNIX. Приведенный ниже код - кроссплатформенная обертка, использующая эти методики. Использование этого кода чревато утечками памяти и не спасает от "кровавого месива", которое может устроить в памяти процесса нестабильно работающий компонент.
Код тестировался на MacOSX 10.6, Windows XP SP3 (msvc) и Ubuntu Linux 10.10
Пример использования:
#include <stdio.h>
#include "crashhandler.h"
int main()
{
try_exec {
int* p = 0;
++(*p);
}
on_crash {
printf( "It crashed!" );
}
printf( " ... but we still alive\n" );
return 0;
}
crashhandler.h
///////////////////////////////////////////////////////////////////////////////
///
/// @file crashhandler.h
///
/// @brief Cross-platform implementation try/except statements for crash handling
///
/// @author Sergeich ( 2sergeich <at> gmail <dot> com )
///
///////////////////////////////////////////////////////////////////////////////
#ifndef CRASH_HANDLER_H
#define CRASH_HANDLER_H
#include <QtGlobal>
#ifdef Q_OS_UNIX
#include <setjmp.h>
#include <signal.h>
///////////////////////////////////////////////////////////////////////////////
typedef void (* SignalHandlerFunc) (int);
class SigactionWrap
{
public:
SigactionWrap( int signum, SignalHandlerFunc handler ) : sig_num(signum)
{
new_action.sa_handler = handler;
sigemptyset(&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (signum, &new_action, &old_action);
}
~SigactionWrap()
{
sigaction (sig_num, &old_action, 0);
}
private:
struct sigaction new_action, old_action;
int sig_num;
};
///////////////////////////////////////////////////////////////////////////////
static sigjmp_buf sigjmp_env;
static void crashHandler( int )
{
siglongjmp (sigjmp_env, 1);
}
#define try_exec \
SigactionWrap segvAct( SIGSEGV, crashHandler ); \
SigactionWrap busAct( SIGBUS, crashHandler ); \
SigactionWrap illAct( SIGILL, crashHandler ); \
SigactionWrap abrtAct( SIGABRT, crashHandler ); \
if ( sigsetjmp( sigjmp_env, 1 ) == 0 )
#define on_crash
#endif // Q_OS_UNIX
///////////////////////////////////////////////////////////////////////////////
#ifdef Q_OS_WIN32
#include <Windows.h>
#define try_exec __try
#define on_crash __except( EXCEPTION_EXECUTE_HANDLER )
#endif // Q_OS_WIN32
#endif // CRASH_HANDLER_H
В аттаче тест для сабжа