c – 如何统一处理所有错误,包括内部C库错误

c – 如何统一处理所有错误,包括内部C库错误,第1张

概述我希望优雅地处理所有内部错误,而无需程序终止. 如here所述,使用_set_se_translator捕获被零除错误. 但是它没有捕获,例如,C运行时库错误-1073740777(0xc0000417),这可能是由printf的格式字符串引起的,它们的百分号不应该出现. (这只是一个例子;当然我们应该检查这样的字符串).要处理这些,需要_set_invalid_parameter_handler 我希望优雅地处理所有内部错误,而无需程序终止.

如here所述,使用_set_se_translator捕获被零除错误.

但是它没有捕获,例如,C运行时库错误-1073740777(0xc0000417),这可能是由printf的格式字符串引起的,它们的百分号不应该出现. (这只是一个例子;当然我们应该检查这样的字符串).要处理这些,需要_set_invalID_parameter_handler.

here还列出了大约十个其他此类处理程序.

另外,这个将捕获未捕获的C异常:SetUnhandledExceptionFilter.因此,它可以与__set__ …函数一起使用. (MSVC 2008中关于using it的文章.)

我想捕获任何和所有错误,以便我可以处理它们(通过记录,抛出现代C标准异常并返回特定于应用程序的错误代码).是否有一个捕获一切的处理程序?

另见StackOverflow.

我正在使用Visual Studio 2008.

解决方法 没有通用处理程序.你需要安装每一个.我用过这样的东西:

///////////////////////////////////////////////////////////////////////////template<class K,class V>class MAPInitializer{    std::map<K,V> m;public:    operator std::map<K,V>() const     {         return m;     }    MAPInitializer& Add( const K& k,const V& v )    {        m[ k ] = v;        return *this;    }};///////////////////////////////////////////////////////////////////////////struct StructuredException : std::exception{    const char *const msg;    StructuredException( const char* const msg_ ) : msg( msg_ ) {}    virtual const char* what() const { return msg; }};///////////////////////////////////////////////////////////////////////////class ExceptionHandlerInstaller{public:    ExceptionHandlerInstaller()        : m_oldTerminateHandler( std::set_terminate( TerminateHandler ) ),m_oldUnexpectedHandler( std::set_unexpected( UnexpectedHandler ) ),m_oldSEHandler( _set_se_translator( SEHandler ) )    {}    ~ExceptionHandlerInstaller()     {         std::set_terminate( m_oldTerminateHandler );        std::set_unexpected( m_oldUnexpectedHandler );        _set_se_translator( m_oldSEHandler );    }private:    static voID TerminateHandler()     {         TRACE( "\n\n**** terminate handler called! ****\n\n" );    }    static voID UnexpectedHandler()     {         TRACE( "\n\n**** unexpected exception handler called! ****\n\n" );    }    static voID SEHandler( const unsigned code,EXCEPTION_POINTERS* )    {        SEMsgMap::const_iterator it = m_seMsgMap.find( code );        throw StructuredException( it != m_seMsgMap.end()             ? it->second             : "Structured exception translated to C++ exception." );    }    const std::terminate_handler  m_oldTerminateHandler;    const std::unexpected_handler m_oldUnexpectedHandler;    const _se_translator_function m_oldSEHandler;    typedef std::map<unsigned,const char*> SEMsgMap;    static const SEMsgMap m_seMsgMap;};///////////////////////////////////////////////////////////////////////////// Message map for structured exceptions copIEd from the MS help file///////////////////////////////////////////////////////////////////////////const ExceptionHandlerInstaller::SEMsgMap ExceptionHandlerInstaller::m_seMsgMap     = MAPInitializer<ExceptionHandlerInstaller::SEMsgMap::key_type,ExceptionHandlerInstaller::SEMsgMap::mapped_type>()    .Add( EXCEPTION_ACCESS_VIolATION,"The thread attempts to read from or write to a virtual address for which it does not have access. This value is defined as STATUS_ACCESS_VIolATION." )    .Add( EXCEPTION_ARRAY_BOUNDS_EXCEEDED,"The thread attempts to access an array element that is out of bounds,and the underlying harDWare supports bounds checking. This value is defined as STATUS_ARRAY_BOUNDS_EXCEEDED." )    .Add( EXCEPTION_BREAKPOINT,"A breakpoint is encountered. This value is defined as STATUS_BREAKPOINT." )    .Add( EXCEPTION_DATATYPE_MISAlignmENT,"The thread attempts to read or write data that is misaligned on harDWare that does not provIDe alignment. For example,16-bit values must be aligned on 2-byte boundarIEs,32-bit values on 4-byte boundarIEs,and so on. This value is defined as STATUS_DATATYPE_MISAlignmENT." )    .Add( EXCEPTION_FLT_DEnorMAL_OPERAND,"One of the operands in a floating point operation is denormal. A denormal value is one that is too small to represent as a standard floating point value. This value is defined as STATUS_float_DEnorMAL_OPERAND." )    .Add( EXCEPTION_FLT_divIDE_BY_ZERO,"The thread attempts to divIDe a floating point value by a floating point divisor of 0 (zero). This value is defined as STATUS_float_divIDE_BY_ZERO." )    .Add( EXCEPTION_FLT_INEXACT_RESulT,"The result of a floating point operation cannot be represented exactly as a decimal fraction. This value is defined as STATUS_float_INEXACT_RESulT." )    .Add( EXCEPTION_FLT_INVALID_OPERATION,"A floatin point exception that is not included in this List. This value is defined as STATUS_float_INVALID_OPERATION." )    .Add( EXCEPTION_FLT_OVERFLOW,"The exponent of a floating point operation is greater than the magnitude allowed by the corresponding type. This value is defined as STATUS_float_OVERFLOW." )    .Add( EXCEPTION_FLT_STACK_CHECK,"The stack has overflowed or underflowed,because of a floating point operation. This value is defined as STATUS_float_STACK_CHECK." )    .Add( EXCEPTION_FLT_UNDERFLOW,"The exponent of a floating point operation is less than the magnitude allowed by the corresponding type. This value is defined as STATUS_float_UNDERFLOW." )    .Add( EXCEPTION_GUARD_PAGE,"The thread accessed memory allocated with the PAGE_GUARD modifIEr. This value is defined as STATUS_GUARD_PAGE_VIolATION." )    .Add( EXCEPTION_ILLEgal_INSTRUCTION,"The thread trIEs to execute an invalID instruction. This value is defined as STATUS_ILLEgal_INSTRUCTION." )    .Add( EXCEPTION_IN_PAGE_ERROR,"The thread trIEs to access a page that is not present,and the system is unable to load the page. For example,this exception might occur if a network connection is lost while running a program over a network. This value is defined as STATUS_IN_PAGE_ERROR." )    .Add( EXCEPTION_INT_divIDE_BY_ZERO,"The thread attempts to divIDe an integer value by an integer divisor of 0 (zero). This value is defined as STATUS_INTEGER_divIDE_BY_ZERO." )    .Add( EXCEPTION_INT_OVERFLOW,"The result of an integer operation causes a carry out of the most significant bit of the result. This value is defined as STATUS_INTEGER_OVERFLOW." )    .Add( EXCEPTION_INVALID_disposition,"An exception handler returns an invalID disposition to the exception dispatcher. Programmers using a high-level language such as C should never encounter this exception. This value is defined as STATUS_INVALID_disposition." )    .Add( EXCEPTION_INVALID_HANDLE,"The thread used a handle to a kernel object that was invalID (probably because it had been closed.) This value is defined as STATUS_INVALID_HANDLE." )    .Add( EXCEPTION_NONCONTINUABLE_EXCEPTION,"The thread attempts to continue execution after a non-continuable exception occurs. This value is defined as STATUS_NONCONTINUABLE_EXCEPTION." )    .Add( EXCEPTION_PRIV_INSTRUCTION,"The thread attempts to execute an instruction with an operation that is not allowed in the current computer mode. This value is defined as STATUS_PRIVILEGED_INSTRUCTION." )    .Add( EXCEPTION_SINGLE_STEP,"A trace trap or other single instruction mechanism signals that one instruction is executed. This value is defined as STATUS_SINGLE_STEP." )    .Add( EXCEPTION_STACK_OVERFLOW,"The thread uses up its stack. This value is defined as STATUS_STACK_OVERFLOW." );

然后在main或app init中,我这样做:

BOol CMyApp::InitInstance(){    ExceptionHandlerInstaller ehi;    // ...}

请注意,这会将结构化异常转换为常规异常,但会通过简单地打印错误消息来处理终止(例如,当nothrow()函数抛出异常时会调用它).您不太可能希望对所有不同类型的错误使用单个处理程序,这就是他们不提供错误的原因.

总结

以上是内存溢出为你收集整理的c – 如何统一处理所有错误,包括内部C库错误全部内容,希望文章能够帮你解决c – 如何统一处理所有错误,包括内部C库错误所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1220253.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存