Skip to content

Instantly share code, notes, and snippets.

@nidefawl
Last active March 11, 2022 22:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nidefawl/33c2eb6cf1ae221098976cfe3820eeae to your computer and use it in GitHub Desktop.
Save nidefawl/33c2eb6cf1ae221098976cfe3820eeae to your computer and use it in GitHub Desktop.
Works with -O0, breaks on -O1
C:\dev\20_CPP\test-seh-exceptions>clang++.exe -O0 -g test_seh_exceptions.cpp -o test_seh_exceptions_O0.exe
C:\dev\20_CPP\test-seh-exceptions>test_seh_exceptions_O0.exe
in __try
in __finally
ret 2, i 5
in __try
in __catch
in __finally
ret -2
Exit 0
C:\dev\20_CPP\test-seh-exceptions>clang++.exe -O1 -g test_seh_exceptions.cpp -o test_seh_exceptions_O1.exe
C:\dev\20_CPP\test-seh-exceptions>test_seh_exceptions_O1.exe
in __try
in __finally
ret -2, i 5
in __try
in __catch
in __finally
ret -2
Exit 0
#include <cstdio>
#include <Windows.h>
extern "C" {
__attribute__((__used__))
LONG WINAPI SehExceptionHandler(EXCEPTION_POINTERS * lpEP) {
return EXCEPTION_EXECUTE_HANDLER;
}
}
__declspec(noinline)
void UnsafeFunction(int* ptr) {
(*ptr)++;
}
__declspec(noinline)
int test_SEH_TryCatch(int* ptr)
{
#define suffix "testsehasm"
volatile int r = 0;
__asm__ __volatile__ ( \
".l_try_begin_" suffix ":\n" \
".seh_handler __C_specific_handler, @except\n" \
".seh_handlerdata\n" \
".long 1\n" \
".rva .l_try_begin_" suffix ", .l_try_end_" suffix ", SehExceptionHandler, .l_catch_" suffix "\n" \
".text\n" \
);
{
std::printf("in __try\n");
UnsafeFunction(ptr);
r = 1;
}
asm ( \
"nop\n" \
".l_try_end_" suffix ":\n" \
"nop\n" \
"jmp .l_finally_" suffix "\n" \
"nop\n" \
".l_catch_" suffix ":\n" \
"nop\n" \
);
{
std::printf("in __catch\n");
r = -1;
}
asm ( \
"nop\n" \
".l_finally_" suffix ":" \
"nop\n" \
);
{
std::printf("in __finally\n");
r *= 2;
}
asm ( \
"nop\n" \
".l_exit_fn_" suffix ":" \
"nop\n" \
);
return r;
}
int main(int, char*[]) {
{
int i = 4;
int r = test_SEH_TryCatch(&i);
std::printf("ret %d, i %d\n", r, i);
}
{
int *p = nullptr;
int r = test_SEH_TryCatch(p);
std::printf("ret %d\n", r);
}
std::printf("Exit 0\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment