windows下使用_set_se_translator,linux下使用sjlj
#include // printf
#include "myException.h"
int main()
{
try
{
MY_EXCEPTION_CHECK
// 0xc0000005
int *p = 0;
*p = 1;
// 0xc0000094
// int x=0;
// int y=0;
// volatile int z=x/y;
}
catch (const MyException &e)
{
printf("myException %s\n", e.what());
}
catch (...)
{
printf("exception...\n");
}
}
#ifndef _MY_EXCEPTION_H
#define _MY_EXCEPTION_H
#ifdef _WIN32
#include // EXCEPTION_POINTERS
#include // _set_se_translator
#else
#include // jmp_buf sigsetjmp
#endif
#include // std::exception
#include // sprintf
#if _WIN32
class MyException : public std::exception
{
public:
MyException(int code) noexcept;
const char *what() const throw();
private:
static void handler(unsigned int u, EXCEPTION_POINTERS *e);
private:
int m_code;
};
#else
class MyException : public std::exception
{
public:
MyException(int code) noexcept;
const char *what() const throw();
private:
static void handler(int code);
private:
int m_code;
};
#endif
#if _WIN32
#define MY_EXCEPTION_CHECK
#else
extern jmp_buf env;
#define MY_EXCEPTION_CHECK \
{ \
int ret = sigsetjmp(env, 1); \
if (0 != ret) \
{ \
throw MyException(ret); \
} \
}
#endif
#endif // _MY_EXCEPTION_H
#include "myException.h"
#if _WIN32
#else
#include // signal
#endif
#if _WIN32
MyException::MyException(int code) noexcept
: m_code(code)
{
_set_se_translator(MyException::handler); // need /EHa
}
const char *MyException::what() const throw()
{
static char str[50];
sprintf(str, "C++ Exception. code: %x", m_code);
return str;
}
void MyException::handler(unsigned int u, EXCEPTION_POINTERS *e)
{
throw MyException(u);
}
#else
jmp_buf env;
MyException::MyException(int code) noexcept
: m_code(code)
{
signal(SIGSEGV, MyException::handler); // segmentation fault
signal(SIGFPE, MyException::handler); // divide by zero
}
const char *MyException::what() const throw()
{
static char str[50];
sprintf(str, "C++ Exception. code: %d", m_code);
return str;
}
void MyException::handler(int code)
{
siglongjmp(env, code);
}
#endif
MyException myException(0);
cmake_minimum_required (VERSION 2.8.12)
project (main)
if(WIN32)
# windows _set_se_translator need /EHa
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GS /EHa")
endif()
include_directories(.)
add_executable(${PROJECT_NAME} main.cpp myException.cpp)