Russian Qt Forum
Май 06, 2024, 19:54 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Кросс-платформенный код для отлова крэшей  (Прочитано 10407 раз)
Sergeich
Гость
« : Октябрь 30, 2010, 14:03 »

Навеяно топиком "Ловля 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

В аттаче тест для сабжа
Записан
zenden
Гость
« Ответ #1 : Октябрь 30, 2010, 15:46 »

Нестабильные компоненты в продакшне? Боже упаси!  Шокированный
Записан
Sergeich
Гость
« Ответ #2 : Октябрь 30, 2010, 19:27 »

Нестабильные компоненты в продакшне? Боже упаси!  Шокированный
Иногда приходиться. Под виндой падает Windows Media Player, под маком - QuickTime и Quartz Composer
Записан
SASA
Гость
« Ответ #3 : Ноябрь 01, 2010, 13:10 »

Я увидел дефайны только для винды и никсов. А как происходит отлов исключений под MacOSX?
Записан
Sergeich
Гость
« Ответ #4 : Ноябрь 01, 2010, 16:17 »

Я увидел дефайны только для винды и никсов. А как происходит отлов исключений под MacOSX?
Mac OS X -  POSIX-совместимая операционная система корпорации Apple.
Записан
iukash
Гость
« Ответ #5 : Апрель 18, 2011, 16:21 »

Не компилится. У меня Windows XP, Qt 4.7, Qt Creator с MinGW. Вот что в консоли
Цитировать
Widget.cpp: In member function 'void Widget::tryToCrash()':

Widget.cpp:38: error: expected 'catch' before '__except'

Widget.cpp:38: error: expected '(' before '__except'

Widget.cpp:38: error: expected type-specifier before '__except'

Widget.cpp:38: error: expected ')' before '(' token

Widget.cpp:38: error: expected '{' before '(' token

Widget.cpp:38: error: expected ';' before '{' token

Widget.cpp:40: warning: statement has no effect
Записан
iukash
Гость
« Ответ #6 : Апрель 28, 2011, 08:13 »

Заменил on_crash на catch(...), все собралось запустилось под виндой должен ловить, но не ловит!  Грустный
Записан
iukash
Гость
« Ответ #7 : Май 01, 2011, 12:05 »

Если поставить Qt под Visual Studio то все работает, проблема только под MinGW!  Грустный
Записан
zenden
Гость
« Ответ #8 : Май 01, 2011, 13:24 »

Потому что Mingw не умеет SEH. Странно, что авторы об этом не подумали...
Записан
Sancho_s_rancho
Гость
« Ответ #9 : Май 01, 2011, 15:26 »

Потому что Mingw не умеет SEH. Странно, что авторы об этом не подумали...
Конечно. Ведь SEH нестандартное расширение причем ломающее стандартный с++ (смешивать с++ исключения и SEH нельзя). Иными словами вас посадят на иглу (Microsoft c++).
Записан
iukash
Гость
« Ответ #10 : Май 25, 2011, 22:17 »

Цитировать
Не компилится. У меня Windows XP, Qt 4.7, Qt Creator с MinGW. Вот что в консоли
Цитировать
Widget.cpp: In member function 'void Widget::tryToCrash()':

Widget.cpp:38: error: expected 'catch' before '__except'

Widget.cpp:38: error: expected '(' before '__except'

Widget.cpp:38: error: expected type-specifier before '__except'

Widget.cpp:38: error: expected ')' before '(' token

Widget.cpp:38: error: expected '{' before '(' token

Widget.cpp:38: error: expected ';' before '{' token

Widget.cpp:40: warning: statement has no effect
Вот эта проблема не решена? Есть ли решения отлова исключения используя Windows и MinGW?
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.049 секунд. Запросов: 20.