You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
3.2 KiB

/*
* Copyright 2002-2019 Intel Corporation.
*
* This software is provided to you as Sample Source Code as defined in the accompanying
* End User License Agreement for the Intel(R) Software Development Products ("Agreement")
* section 1.L.
*
* This software and the related documents are provided as is, with no express or implied
* warranties, other than those that are expressly stated in the License.
*/
/*
This application causes exception in indirect call instruction and catches it in caller.
The call instruction is located in code region being replaced by Pin probe.
Pin translation should not affect propagation of the exception to the C++ exception handler.
*/
#include <stdio.h>
bool destructed = false;
// cpp exceptions - Exercise windows exception mechanism
class MyClass
{
public:
~MyClass()
{
destructed = true;
}
};
extern "C" void ExcInDll();
static int (*pBar)() = 0;
extern "C" unsigned long getstack();
extern "C" unsigned long getebp();
int bar()
{
return 0;
}
extern "C"
void foo1()
{
if (!pBar) throw(0);
// May cause exception due to NULL pointer
pBar();
}
extern "C"
void foo2()
{
ExcInDll();
}
int main()
{
int local = 1;
unsigned long stackBefore = getstack();
unsigned long framePtrBefore = getebp();
try
{
MyClass ins;
foo1();
local = 0;
}
catch(...)
{
// If Pin translated probed code properly, exception will reach the handler
printf("Exception\n");
}
unsigned long stackAfter = getstack();
unsigned long framePtrAfter = getebp();
if ((stackBefore != stackAfter) || (framePtrBefore != framePtrAfter))
{
printf("before try Stack at 0x%x, ebp 0x%x\n", getstack(), getebp());
printf("after catch Stack at 0x%x, ebp 0x%x\n", getstack(), getebp());
return -1;
}
int param1 = 1;
int param2 = param1 * 5;
float param3 = 0.5*1.5;
float expectedResult = 0;
try
{
expectedResult = param3+param2+param1;
foo2();
}
catch(...)
{
float afterCatchResult = param3+param2+param1;
if (afterCatchResult != expectedResult)
{
printf("expectedResult = %f; afterCatchResult = %f\n", expectedResult, afterCatchResult);
printf("Registers may be restored incorrectly in the catch block\n");
return -1;
}
else
{
printf("Try-catch works correctly while exception propagation from dll\n");
}
}
stackAfter = getstack();
framePtrAfter = getebp();
if ((stackBefore != stackAfter) || (framePtrBefore != framePtrAfter))
{
printf("Incorrect stack of frame ptr after exception propagation from dll");
printf("before try Stack at 0x%x, ebp 0x%x\n", getstack(), getebp());
printf("after catch Stack at 0x%x, ebp 0x%x\n", getstack(), getebp());
return -1;
}
// Check that destructor was called and local var value was not changed when exception was handled
if (!destructed || (local != 1))
{
return 1;
}
pBar = bar;
try
{
foo1();
}
catch(...)
{
// No exception expected
printf("Exception\n");
}
return 0;
}