NOTE: THIS INFORMATION MAY NO LONGER BE RELEVANT AS CLANG HAS PARTIAL SEH SUPPORT FOR BOTH X86 AND X86_64! THIS PAGE REMAINS HERE FOR HISTORICAL PURPOSES.
Note: This is alpha grade code. But then again, it might work very well. It seems to work in my limited testing so far.
NewsAs of 12-05-2011, the latest version is v0.0.4, which fixes several issues.
About LibSEHLibSEH is a compatibility layer that allows one to utilize the Structured
Exception Handling facility found in Windows within GNU C/C++ for Windows (MINGW32, CYGWIN).
In other compilers, SEH is built into the compiler as a language extension. In other
words, this syntax is not standard C or C++, where standard in this case includes any
ANSI standard. Usually, support for this feature is implemented through
#include <windows.h> #include <stdio.h> int ExceptionFilter(unsigned int code, unsigned int excToFilter) { if(code == excToFilter) return EXCEPTION_EXECUTE_HANDLER; else return EXCEPTION_CONTINUE_SEARCH; } int main() { int x = 0; int y = 4; __try { y /= x; } __except(ExceptionFilter(GetExceptionCode(), EXCEPTION_INT_DIVIDE_BY_ZERO)) { printf("Divide by zero exception.\n"); } return 0; }
This is only supported in Microsoft C/C++ and Digital Mars C/C++. These are not standard language constructs.
LibSEH allows programs intended for GNU C/C++ to utilize this feature, with a high degree of source-level compatibility, resulting in minimal changes to existing code. To modify the above program in order to compile it on GNU C/C++ with LibSEH, a few changes need to be made:
#include <windows.h> #include <stdio.h> #include <seh.h> /* The LibSEH header needs to be included */ int ExceptionFilter(unsigned int code, unsigned int excToFilter) { if(code == excToFilter) return EXCEPTION_EXECUTE_HANDLER; else return EXCEPTION_CONTINUE_SEARCH; } int main() { int x = 0; int y = 4; __seh_try /* __try becomes __seh_try */ { y /= x; } __seh_except(ExceptionFilter(GetExceptionCode(), /* __except becomes __seh_except */ EXCEPTION_INT_DIVIDE_BY_ZERO)) { printf("Divide by zero exception.\n"); } __seh_end_except /* This must terminate all __seh_except blocks */ return 0; }
The seh.h header includes other headers, and when preprocessed
under Microsoft C/C++ and Digital Mars C/C++ (untested), the
All of this allows the same source to be compiled on GNU C/C++ and Microsoft C/C++ (and most likely, Digital Mars C/C++).
The library also supports the
int main() { int x = 0; int y = 4; __seh_try { __seh_try { y /= x; } __seh_finally { printf("Leaving __seh_try/__seh_finally compound statement.\n"); } __seh_end_finally /* NOTE THE __seh_end_finally, also required */ } __seh_except(ExceptionFilter(GetExceptionCode(), EXCEPTION_INT_DIVIDE_BY_ZERO)) { printf("Divide by zero exception.\n"); } __seh_end_except return 0; }
The
LibSEH does not have the exact same behavior as builtin SEH in Microsoft C/C++. Here are some of the currently known differences (and I could be incorrect, as I haven't tested all of these):
These differences only affect when LibSEH is really being used, like when using GNU C/C++.
In certain cases, if a variable is modified within a
An example (illustration only):
volatile HANDLE hFile = NULL; __seh_try { hFile = CreateFile(...); /* Do something that raises an exception */ } __seh_except(EXCEPTION_EXECUTE_HANDLER) { /* Without the volatile modifier, hFile could still be NULL here, even if the exception is raised after the CreateFile call and even if that call does not return NULL. */ if(hFile) { CloseHandle(hFile); } } __seh_end_except
This presents a problem with GCC in some cases unless the -O0 (no optmization) option is used when compiling.
A note concerning C++: LibSEH does not unwind the stack in the same way that the C++ runtime library does, and as a consequence, destructors are not called when objects go out of scope from stack unwinding when dealing with an exception. This can lead to resource leaks if one isn't careful. The library does include a C++ interface (which translates SEH (system) exceptions into C++ exceptions), however.
Changesv0.0.4 fixes some macro conflicts with libstdc++ as well as several other issues and adds the __seh_leave macro.
v0.0.3 fixes some GCC 3.x compatibility issues.
Versions v0.0.2 and up are compatible with GCC 4.x, whereas v0.0.1 is not. v0.0.2 also fixes some issues that apply to optimized builds.
When Problems OccurIf a problem occurs with a program that uses libseh in terms of SEH (exceptions not being caught that occur, stack variables mysteriously changing in subroutines that use __seh_try/__seh_except, etc), it is suggested that one compile the application without optimizations. Bug reports are always welcome.
Download (alpha)libseh-0.0.4.zip (Source code)
libseh-0.0.3.zip (Source code)
libseh-0.0.2.zip (Source code)
libseh-0.0.1.zip (Source code)