Home > Programming, Windows > Mixing SEH and C++ EH

Mixing SEH and C++ EH

Some people have noticed my use of two classes (SehGuard and SehException) in a lot of my code and became curious. The reason I’m using them is so I can mix C++ exception handling with structured exception handling. Obviously if you enable C++ with SEH Exceptions in your compiler you can catch SEH exceptions with ‘catch(…)’ but unforutunately you don’t get an object with which you can get any useful information. I went searching for a workaround and found this blog post.

The following is my implementation of the two classes, which is based off the code in that original post (tstring, tcout, etc are just preprocessor defines that resolve to either string/cout/etc or wstring/wcout/etc depending on whether Unicode is defined or not).


// Use pragma directive if supported.

#pragma once

// Use preprocessor header guards if pragma once is unavailable

// Required to ensure portability

#ifndef __CERBERUS__SEH_H

#define __CERBERUS__SEH_H

// Cerberus

#include “StringWrap.h”

// Windows API

#include <Windows.h>

// C++ Standard Library

#include <iostream>

// Function-local SEH guard. Proxies SEH to C++ EH

// Catch via SehException

class SehGuard






void* m_prev;


// SEH proxy exception.

// Catch this to catch structured exceptions as C++ exceptions.

// Must have SehGuard object created for it to work (function-local).

class SehException



SehException(int Code, struct _EXCEPTION_POINTERS* pException);

DWORD GetCode() const;

PVOID GetAddress() const;

struct _EXCEPTION_POINTERS* GetExceptionPointers() const;


unsigned int m_Code;

struct _EXCEPTION_POINTERS* m_pException;


// Ostream overload for SehException. To make debug output easier.

std::tostream& operator<< ( std::tostream& out, const SehException& x );

// SEH to C++ EH proxy function

extern void SehTranslatorFunction(unsigned int, struct _EXCEPTION_POINTERS*);

// Generic unhandled exception filter

extern LONG WINAPI MyGenericUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* ExceptionInfo);

#endif // __CERBERUS__SEH_H

// Cerberus
#include “Seh.h”
#include “StringWrap.h”
// Windows API
#include <Windows.h>
#include <Dbghelp.h>
#include <eh.h>
#include <tchar.h>
// C++ Standard Library
#include <string>
#include <vector>
// Proxies SEH to C++ EH
void SehTranslatorFunction(unsigned int Code, struct _EXCEPTION_POINTERS* pException)
throw SehException(Code,pException);
// Constructor
// Set SEH translator
m_prev = _set_se_translator(SehTranslatorFunction);
// Destructor
// Reset SEH translator
// Proxy exception constructor
SehException::SehException( int Code, struct _EXCEPTION_POINTERS* pException )
: m_Code(Code), m_pException(pException)
{ }
// Get exception code
DWORD SehException::GetCode() const
return m_Code;
// Get exception address
PVOID SehException::GetAddress() const
return m_pException->ExceptionRecord->ExceptionAddress;
// Get exception data pointer
struct _EXCEPTION_POINTERS* SehException::GetExceptionPointers() const
return m_pException;
// Ostream overload for SehException. To make debug output easier.
// TODO: Full output for x86 and x64 with registers, stack trace, etc
std::tostream& operator<<( std::tostream& out, const SehException& x )
out << _T(”Code: “) << std::hex << x.GetCode() << _T(”. Address: “)
<<  x.GetAddress() << std::dec << _T(”.”);
return out;
// Generic unhandled exception filter
LONG WINAPI MyGenericUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* ExceptionInfo)
// Get the current time
GetLocalTime( &sTime );
// Pull out the date
std::vector<TCHAR> Date(10);
GetDateFormat(LOCALE_USER_DEFAULT, 0, &sTime, _T(”yyyyMMdd”), &Date[0],
// Pull out the time
std::vector<TCHAR> Time(10);
_T(”hhmmss”), &Time[0], 10);
// Create a filename for the crash dump out of the current
// date and time.
std::tstring Path(TEXT(”Crash-”));
// Create file to dump output
HANDLE hFile = CreateFile(Path.c_str(), GENERIC_WRITE, 0, NULL,
// Create minidump
aMiniDumpInfo.ThreadId = GetCurrentThreadId();
aMiniDumpInfo.ExceptionPointers = ExceptionInfo;
aMiniDumpInfo.ClientPointers = TRUE;
// Write minidump
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile,
(MINIDUMP_TYPE) (MiniDumpWithFullMemory|MiniDumpWithHandleData),
&aMiniDumpInfo, NULL, NULL);
// Close file handle
// Execute handler
Usage is fairly simple. Dump a SehGuard in your try block, and catch the SehException as you would any other. It makes programming for Windows in C++ about a lot easier and more natural.
  1. No comments yet.
  1. No trackbacks yet.