Click here to Skip to main content
11,479,083 members (59,591 online)
Click here to Skip to main content

Tagged as

SEH and C++ Exceptions - catch all in one

, 16 Mar 2000 205K 3.3K 87
Rate this:
Please Sign up or sign in to vote.
This article describes how to handle SE and C++ exception together.
  • Download demo project - 15 Kb
  • Download source files - 2 Kb
  • Motivation

    Everybody sometimes need to write as robust code as possible. The simplest way, in these cases, is to use exception handling. But most code is wrote in C++/MFC, with C++ exception handling (e.g. CdbException). With SEH, it is not possible to catch C++ exception, and C++ typed exception can not catch SE selectively, because it is not typed in a way of C++. Solution with catch(...) is not useful, because you will not know 'type' of exception. SE is possible to catch like unsigned int typed C++ exception, but this solution is not very nice.  

    Description of solution

    I was looking for a method to handle SE and C++ exception together. I found function

    typedef void (*_se_translator_function)( unsigned int, struct _EXCEPTION_POINTERS* );
    

    In MSDN you can find following description:

    The _set_se_translator function provides a way to handle Win32 exceptions (C structured exceptions) as C++ typed exceptions. To allow each C exception to be handled by a C++ catch handler, first define a C exception "wrapper" class that can be used, or derived from, in order to attribute a specific class type to a C exception. To use this class, install a custom C exception translator function that is called by the internal exception-handling mechanism each time a C exception is raised. Within your translator function, you can throw any typed exception that can be caught by a matching C++ catch handler.

    And now, it is enough to write wrapper class (I think, my class is quite better than class provided by documentation for _set_se_translator):

    class CSeException : public CException
    {
      DECLARE_DYNAMIC(CSeException)
          
    public: 
        CSeException(UINT nSeCode, _EXCEPTION_POINTERS* pExcPointers);
        CSeException(CSeException & CseExc);
    
        UINT GetSeCode(void);
        _EXCEPTION_POINTERS* GetSePointers(void);
        PVOID GetExceptionAddress(void);
    
        void Delete(void);
        int ReportError(UINT nType = MB_OK, UINT nIDHelp = 0);
        BOOL GetErrorMessage(CString & CsErrDescr, PUINT pnHelpContext = NULL);
        BOOL GetErrorMessage(LPTSTR lpszError, 
                             UINT nMaxError, 
                             PUINT pnHelpContext = NULL);
          
    private:
        UINT m_nSeCode;
        _EXCEPTION_POINTERS* m_pExcPointers;
    };
    

    And my own translator function:

    void SeTranslator(UINT nSeCode, _EXCEPTION_POINTERS* pExcPointers)
    {
       throw new CSeException(nSeCode,pExcPointers);
    }
    

    How does it work?

    When SE is raised, then it is called our own translator function - if it was installed through _se_translator_function. This translator function simply throw exception again, but now it is our wrapper class exception filled with useful information.

    Description of CSeException

    CSeException class is based on CException class provided by MFC. I overwrite some of useful methods, but it is working same way like any other exception class based on CException class - you can find description in documentation provided by Visual C++.

    Usage

    At first of all you need to install SeTranslator function, in every thread of your application. Translator function is  thread specific, it means it is not globally set in application. In single thread application it is possible to install it in constructor of application class (as I do in demo program), however in multithreading application it is best place to install translator function at the beginnings of every thread. When translator function is installed, then it is possible to write code like this:

    char *p = NULL;
    
    try {
    
      // do something ...
    
      p[0] = 0; 
    
      // do something ...
    
    } catch (CdbException dbError) {
    
      //handle it
    
    } catch(CSeException *e) {
      e->ReportError(MB_OK | MB_ICONSTOP);
      e->Delete();
    }
    

    CSeException class is Unicode and MBCS strings compliant. Please note, delete CSeException in catch() block, because it is dynamically allocated by translator function.

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here

    Share

    About the Author

    Martin Ziacek
    Software Developer (Senior)
    United Kingdom United Kingdom
    No Biography provided

    Comments and Discussions

     
    QuestionLicense? Pin
    jcastrovinci1-Feb-10 9:35
    memberjcastrovinci1-Feb-10 9:35 
    Questionunable to catch breakpoint exceptions Pin
    hans.sch23-Nov-09 8:35
    memberhans.sch23-Nov-09 8:35 
    QuestionHow to do it well if _set_se_translator() is not available (WinCE) Pin
    Bostjan Erzen26-Aug-08 1:41
    memberBostjan Erzen26-Aug-08 1:41 
    QuestionAhoj Martin, prosba o pomoc Pin
    riavale23-Mar-06 7:30
    memberriavale23-Mar-06 7:30 
    GeneralImproved Error Message for Access Violations Pin
    Steve Johnson (Sven)22-Mar-06 11:58
    memberSteve Johnson (Sven)22-Mar-06 11:58 
    GeneralYou can't catch and continue on all Pin
    DB115-Oct-05 18:34
    memberDB115-Oct-05 18:34 
    GeneralCompiler switch "/EHa" needed with VC 6 & 7 Pin
    Jamireste28-Sep-05 6:43
    memberJamireste28-Sep-05 6:43 
    Questionfloating point exceptions as well? Pin
    cptspiff28-Nov-03 2:00
    membercptspiff28-Nov-03 2:00 
    Generalmore Exceptions Pin
    gertano24-Mar-03 8:52
    membergertano24-Mar-03 8:52 
    GeneralRe: more Exceptions Pin
    Martyn Pearson18-Jun-03 1:19
    memberMartyn Pearson18-Jun-03 1:19 
    GeneralRe: more Exceptions Pin
    Anonymous2-Sep-04 0:10
    sussAnonymous2-Sep-04 0:10 
    GeneralQuestion about design. Pin
    Holy Punk6-Feb-03 16:36
    sussHoly Punk6-Feb-03 16:36 
    GeneralRe: Question about design. Pin
    Mike U.29-Apr-03 0:32
    sussMike U.29-Apr-03 0:32 
    GeneralRelease mode weirdness Pin
    booster16-Nov-01 5:44
    memberbooster16-Nov-01 5:44 
    GeneralRe: Release mode weirdness Pin
    Martin Ziacek16-Nov-01 10:19
    memberMartin Ziacek16-Nov-01 10:19 
    GeneralMFC Independent Pin
    Anonymous5-Nov-01 19:26
    memberAnonymous5-Nov-01 19:26 
    GeneralRe: MFC Independent Pin
    Martin Ziacek5-Nov-01 20:35
    memberMartin Ziacek5-Nov-01 20:35 
    Questionmultiple calls i n a thread? Pin
    Anonymous22-Oct-01 9:12
    memberAnonymous22-Oct-01 9:12 
    AnswerRe: multiple calls i n a thread? Pin
    Martin Ziacek31-Oct-01 5:36
    memberMartin Ziacek31-Oct-01 5:36 
    Questionwhat about exception type? Pin
    Anonymous22-Oct-01 8:47
    memberAnonymous22-Oct-01 8:47 
    AnswerRe: what about exception type? Pin
    Martin Ziacek31-Oct-01 5:30
    memberMartin Ziacek31-Oct-01 5:30 
    GeneralThread Problem Pin
    Thomas George10-Sep-01 11:37
    memberThomas George10-Sep-01 11:37 
    GeneralRe: Thread Problem Pin
    Martin Ziacek10-Sep-01 12:01
    memberMartin Ziacek10-Sep-01 12:01 
    GeneralRe: Thread Problem Pin
    Thomas George10-Sep-01 13:49
    memberThomas George10-Sep-01 13:49 
    Thanks for the reply ...
    but it still does not work.

    What I am doing is:

    _beginthreadex(NULL, 0, ThreadProc, this, 0, &nThreadId);

    In ThreadProc

    _set_se_translator(trans_func);
    // code to create exception

    When run, this never reaches the trans_func. Instead the access violation error comes up in the standard dialog box.

    But the same thing works fine from the primary thread of the application.

    Thank you

    Thomas
    GeneralRe: Thread Problem Pin
    Martin Ziacek10-Sep-01 20:01
    memberMartin Ziacek10-Sep-01 20:01 
    GeneralRe: Thread Problem Pin
    Thomas George11-Sep-01 13:04
    memberThomas George11-Sep-01 13:04 
    GeneralRe: Thread Problem Pin
    Martin Ziacek12-Sep-01 11:01
    memberMartin Ziacek12-Sep-01 11:01 
    GeneralSame Thread Problem Pin
    kcselvaraj28-May-06 21:28
    memberkcselvaraj28-May-06 21:28 
    GeneralUnable use the exception class Pin
    RameshKumar23-Jul-01 5:01
    memberRameshKumar23-Jul-01 5:01 
    GeneralRe: Unable use the exception class Pin
    Martin Ziacek24-Jul-01 6:48
    memberMartin Ziacek24-Jul-01 6:48 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

    | Advertise | Privacy | Terms of Use | Mobile
    Web01 | 2.8.150520.1 | Last Updated 17 Mar 2000
    Article Copyright 2000 by Martin Ziacek
    Everything else Copyright © CodeProject, 1999-2015
    Layout: fixed | fluid