SEH and C++ Exceptions - catch all in one
Environment: Visual C++ 5.0 & SP3, Windows NT 4.0 & SP5, Unicode, MBCS
This article describes how to handle SE and C++ exception together.
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.
Download

Comments
RE:SEH and C++ Exceptions - catch all in one
Posted by Legacy on 07/18/2002 12:00amOriginally posted by: Daniel Slater
ReplySEH and C++ exceptions do not necessarily work and play well together
Posted by Legacy on 02/20/2001 12:00amOriginally posted by: Eric Smith
ReplyRe: C++ Exceptions not Caught!!!
Posted by Legacy on 02/15/2000 12:00amOriginally posted by: Martin Ziacek
Hi Mark,
You can not catch exception from CFile::Remove(),
because it throws CFileException and not CFileException *.
Martin
ReplyC++ Exceptions not Caught!!!
Posted by Legacy on 01/24/2000 12:00amOriginally posted by: Mark
ReplyAnother form of Unhandled Exeption Trapping
Posted by Legacy on 06/01/1999 12:00amOriginally posted by: Jeff Boyle
While this is nice, I think you should also check out John Robbins web site....he is an author for MSJ (he writes the BugSlayer column) and works for NuMega....he has a wonderful DLL which does all this and much much more, and he also provides source. I think you can get his articles from the magazine on the web also.
The site is: www.jprobbins.com
Look for the BugSLayerUtil.DLL
Reply