mirror of
https://github.com/reactos/reactos.git
synced 2024-09-05 18:26:53 +00:00
![Timo Kreuzer](/assets/img/avatar_default.png)
* [COMPILER_APITEST] Import MS EH/SEH tests Taken from https://github.com/microsoft/compiler-tests * [CRT] Add missing declaration of _longjmpex * [COMPILER_APITEST] Add cmake build files for MS SEH test It is built as a static library * [COMPILER_APITEST] Fix GCC build of MS SEH tests There are a number of hacks in there now. Also the volatile hacks should be separated and sent upstream. * [COMPILER_APITEST] Fix x64 build of MS SEH tests * [COMPILER_APITEST] Fix clang build of MS SEH tests * [COMPILER_APITEST] Include MS SEH tests
124 lines
2.5 KiB
C++
124 lines
2.5 KiB
C++
// Copyright (c) Microsoft. All rights reserved.
|
|
// Licensed under the MIT license. See LICENSE file in the project root for
|
|
// full license information.
|
|
|
|
/*
|
|
** The first call to Test checks to make sure that we don't call terminate
|
|
** when an SEH fault is triggered. After catching the SEH fault, we then
|
|
** cause a C++ EH fault (where the destructed object is in the try-block
|
|
** that threw the exception). The C++ EH fault in the dtor should cause
|
|
** a call to terminate(); in this case, we register our own handler to
|
|
** trap the call to terminate(). We then run a second C++ EH fault (where
|
|
** the destructed object is higher in the call tree than where the
|
|
** exception was thrown). We trap this call to terminate() as well (with
|
|
** a different handler) and then exit.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <eh.h>
|
|
|
|
int FGenSEHException;
|
|
|
|
class C
|
|
{
|
|
public:
|
|
C() {}
|
|
~C()
|
|
{
|
|
printf( "in C::~C()\n");
|
|
if (FGenSEHException)
|
|
{
|
|
printf("generating access violation (SEH)\n");
|
|
*(volatile char*)(0) = 0; // Uh, EHa, don't you think?
|
|
}
|
|
else
|
|
{
|
|
printf("throwing C++ exception\n");
|
|
throw 'a';
|
|
}
|
|
}
|
|
};
|
|
|
|
int Test()
|
|
{
|
|
try
|
|
{
|
|
C c;
|
|
throw 1;
|
|
}
|
|
catch (int)
|
|
{
|
|
printf("Destructor was not invoked \n");
|
|
}
|
|
catch (char)
|
|
{
|
|
printf("Destructor exited using an exception\n");
|
|
}
|
|
#if 0
|
|
catch (...)
|
|
{
|
|
printf("Throw caught by wrong handler\n");
|
|
}
|
|
#endif
|
|
|
|
printf("terminate() was not called\n");
|
|
|
|
return 1;
|
|
}
|
|
|
|
void Bar(void)
|
|
{
|
|
printf("in %s\n", __FUNCTION__);
|
|
throw 1;
|
|
}
|
|
|
|
void Test2(void)
|
|
{
|
|
printf("in %s\n", __FUNCTION__);
|
|
C c;
|
|
Bar();
|
|
return;
|
|
}
|
|
|
|
void __cdecl Terminate2(void)
|
|
{
|
|
printf("termination handler (%s) called\n", __FUNCTION__);
|
|
exit(0);
|
|
}
|
|
|
|
void __cdecl Terminate1(void)
|
|
{
|
|
printf("termination handler (%s) called\n", __FUNCTION__);
|
|
|
|
// Set a new handler and run a second C++ EH test case.
|
|
set_terminate(Terminate2);
|
|
Test2();
|
|
exit(0);
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
int i;
|
|
|
|
// First check that we don't terminate on an SEH exception
|
|
FGenSEHException = 1;
|
|
__try
|
|
{
|
|
i = Test();
|
|
}
|
|
__except (1)
|
|
{
|
|
printf("caught SEH exception in %s\n", __FUNCTION__);
|
|
}
|
|
|
|
// Now set our own terminate handler and throw a C++ EH exception
|
|
set_terminate(Terminate1);
|
|
FGenSEHException = 0;
|
|
i = Test();
|
|
|
|
// Should never get here
|
|
printf("termination handler not called\n");
|
|
return i;
|
|
}
|