/* * 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. */ #include #include #include #include #include #include "pin.H" using std::cerr; using std::endl; static BOOL HandleSig(THREADID, INT32, CONTEXT *, BOOL hndlr, const EXCEPTION_INFO *, VOID *); static BOOL ParseCmdLine(int, char **); static void Usage(); // These parameters are set from the tool's command line int Signal = SIGINT; // Signal to intercept unsigned Count = 1; // Tool exits after intercepting signal this many times BOOL PassToApp = FALSE; // Whether intercepted signals should be passed to application handler int main(int argc, char **argv) { PIN_Init(argc, argv); if (!ParseCmdLine(argc, argv)) return 1; PIN_InterceptSignal(Signal, HandleSig, 0); PIN_UnblockSignal(Signal, TRUE); PIN_StartProgram(); return 0; } static BOOL HandleSig(THREADID tid, INT32 sig, CONTEXT *ctxt, BOOL hndlr, const EXCEPTION_INFO *exception, VOID *v) { std::cerr << "Thread : " << tid << " Intercepting signal " << sig << std::endl; if (exception) std::cerr << "Signal is an exception" << std::endl; else std::cerr << "Signal is not an exception" << std::endl; if (--Count == 0) exit(0); return PassToApp; } static BOOL ParseCmdLine(int argc, char **argv) { // Skip over the Pin arguments. // int i; for (i = 0; i < argc; i++) { if (strcmp(argv[i], "-t") == 0 && (i+2 < argc)) { i += 2; break; } } bool done = false; for (; i < argc && !done; i++) { if (argv[i][0] != '-') { Usage(); return FALSE; } switch (argv[i][1]) { case 's': { if (i+1 >= argc) { Usage(); return FALSE; } Signal = strtol(argv[i+1], 0, 10); if (Signal < 1 || Signal > 64) { cerr << "Invalid signal number: " << argv[i+i] << endl; Usage(); return FALSE; } i++; break; } case 'c': { if (i+1 >= argc) { Usage(); return FALSE; } unsigned long count = strtoul(argv[i+1], 0, 10); if (count == 0 || count > UINT_MAX) { cerr << "Invalid count, must be greater than zero: " << argv[i+1] << endl; Usage(); return FALSE; } Count = static_cast(count); i++; break; } case 'p': { PassToApp = TRUE; break; } case '-': { done = TRUE; break; } default: { cerr << "Invalid argument: " << argv[i] << endl; Usage(); return FALSE; } } } return TRUE; } static void Usage() { cerr << endl; cerr << "pin -t intercepttool [-s ] [-c ] [-p]" << endl; cerr << " -s - Specifies signal to intercept (default is SIGINT)" << endl; cerr << " -c - Tool exits after intercepting signal this many times (default 1)" << endl; cerr << " -p - Tool forwards signal to application after intercepting" << endl; cerr << endl; }