• C++异常捕获


    C++异常捕获

    windows下使用_set_se_translator,linux下使用sjlj

    • main.cpp
    #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");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • myException.h
    #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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • myException.cpp
    #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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • CMakeLists.txt
    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    RabbitMQ:工作队列模式
    漏洞利用工具的编写
    固件签名的安全解决方案 安当加密
    vue-引入使用main.js全局常量
    激活函数(机器学习)
    python.tkinter设计标记语言(转译2-html)
    SpringCloud微服务 【实用篇】| 认识微服务
    TiDB Lightning 故障处理
    .NET 控制台NLog 使用
    ALEXNET论文及其复现代码
  • 原文地址:https://blog.csdn.net/itas109/article/details/134019698