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.
146 lines
4.2 KiB
146 lines
4.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 tool replays a windows exception. It is intended to be
|
|
* used with the win_exception.c test.
|
|
*/
|
|
#include <stdio.h>
|
|
#include "pin.H"
|
|
|
|
static FILE * out;
|
|
|
|
VOID Fini(INT32 code, VOID *v)
|
|
{
|
|
fprintf(out, "PinFiniFunction\n");
|
|
fclose(out);
|
|
}
|
|
|
|
static CONTEXT savedFromContext;
|
|
static CONTEXT savedToContext;
|
|
static INT32 savedReason;
|
|
|
|
static int exceptionCount = 0;
|
|
static BOOL foundReplayException = FALSE;
|
|
static BOOL foundReadyForException = FALSE;
|
|
static BOOL toolIsReadyForException = FALSE;
|
|
|
|
static VOID OnException(THREADID threadIndex,
|
|
CONTEXT_CHANGE_REASON reason,
|
|
const CONTEXT *ctxtFrom,
|
|
CONTEXT *ctxtTo,
|
|
INT32 info,
|
|
VOID *v)
|
|
{
|
|
if (!toolIsReadyForException && reason == CONTEXT_CHANGE_REASON_EXCEPTION)
|
|
{
|
|
fprintf (out, "See exception %d : info 0x%x from 0x%0x but this is not the exception we want to replay\n", exceptionCount, info,
|
|
PIN_GetContextReg(ctxtFrom, REG_INST_PTR));
|
|
return;
|
|
}
|
|
if (!foundReplayException)
|
|
{
|
|
fprintf (out, "Failed to instrument ReplayException!\n");
|
|
}
|
|
if (reason == CONTEXT_CHANGE_REASON_EXCEPTION)
|
|
{
|
|
if (exceptionCount++ == 0)
|
|
{
|
|
PIN_SaveContext (ctxtFrom, &savedFromContext);
|
|
PIN_SaveContext (ctxtTo, &savedToContext);
|
|
savedReason = info;
|
|
}
|
|
fprintf (out, "See exception %d : info 0x%x from 0x%0x\n", exceptionCount, info,
|
|
PIN_GetContextReg(ctxtFrom, REG_INST_PTR));
|
|
fflush(out);
|
|
|
|
if (exceptionCount == 2)
|
|
{
|
|
// Check that the second exception is the same as the first, at least to a first approximation.
|
|
if (info == savedReason &&
|
|
PIN_GetContextReg(ctxtFrom, REG_INST_PTR) == PIN_GetContextReg(&savedFromContext, REG_INST_PTR))
|
|
{
|
|
fprintf (out, "Second exception looks like a replay, good!\n");
|
|
fflush(out);
|
|
exit(0);
|
|
}
|
|
else
|
|
{
|
|
fprintf (out, "Second exception does not look like a replay, BAD!\n");
|
|
fflush(out);
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static VOID reRaiseException(THREADID tid)
|
|
{
|
|
if (exceptionCount == 0)
|
|
{
|
|
fprintf (out, "Trying to replaying the first exception, but we haven't seen one!\n");
|
|
return;
|
|
}
|
|
fprintf (out, "Replaying the first exception\n");
|
|
fflush(out);
|
|
PIN_ReplayContextChange(tid, &savedFromContext, &savedToContext, CONTEXT_CHANGE_REASON_EXCEPTION, savedReason);
|
|
}
|
|
|
|
static VOID ToolReadyForExceptionFromAppMain()
|
|
{
|
|
toolIsReadyForException = TRUE;
|
|
}
|
|
|
|
static VOID Image(IMG img, VOID *v)
|
|
{
|
|
if (foundReplayException && foundReadyForException)
|
|
return;
|
|
|
|
// hook the functions in the image. If these functions are called then it means
|
|
// that pin has not lost control.
|
|
RTN rtn = RTN_FindByName(img, "ReplayException");
|
|
if (RTN_Valid(rtn))
|
|
{
|
|
RTN_Open(rtn);
|
|
RTN_InsertCall(rtn, IPOINT_BEFORE, AFUNPTR(reRaiseException), IARG_THREAD_ID, IARG_END);
|
|
RTN_Close(rtn);
|
|
foundReplayException = TRUE;
|
|
}
|
|
|
|
rtn = RTN_FindByName(img, "ReadyForExceptionFromAppMain");
|
|
if (RTN_Valid(rtn))
|
|
{
|
|
RTN_Open(rtn);
|
|
RTN_InsertCall(rtn, IPOINT_BEFORE, AFUNPTR(ToolReadyForExceptionFromAppMain), IARG_END);
|
|
RTN_Close(rtn);
|
|
foundReadyForException = TRUE;
|
|
}
|
|
}
|
|
|
|
int main(INT32 argc, CHAR **argv)
|
|
{
|
|
out = fopen("win_replay_exception.out", "w");
|
|
|
|
PIN_InitSymbols();
|
|
PIN_Init(argc, argv);
|
|
|
|
PIN_AddContextChangeFunction(OnException, 0);
|
|
|
|
IMG_AddInstrumentFunction(Image, 0);
|
|
|
|
PIN_AddFiniFunction(Fini, 0);
|
|
|
|
// Never returns
|
|
PIN_StartProgram();
|
|
|
|
return 0;
|
|
}
|