/* * 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. */ /*! @file * * A test for attach to single threaded application. * The application launches Pin and waits until Pin attaches */ #include #include #include #include #include #include #include #include using std::list; using std::string; typedef bool (*FUNPTR)(); /* Pin doesn't kill the process if failed to attach, exit on SIGALRM */ void ExitOnAlarm(int sig) { fprintf(stderr, "Pin is not attached, exit on SIGALRM\n"); exit(0); } extern "C" bool PinAttached() { return false; } /* * Expected command line: [-th_num NUM] -pin $PIN -pinarg -t tool */ void ParseCommandLine(int argc, char *argv[], list < string>* pinArgs)//, list < string>* pinBinaryArgs) { string pinBinary; string beforePinArgs; for (int i=1; ipush_back(arg); for (int parg = ++i; parg < argc; parg++) { pinArgs->push_back(string(argv[parg])); ++i; } } } if (!beforePinArgs.empty()) { pinArgs->push_front(beforePinArgs); } assert(!pinBinary.empty()); pinArgs->push_front(pinBinary); } void StartPin(list * pinArgs) { pid_t appPid = getpid(); pid_t child = fork(); if (child > 0) { return; } else if (0 == child) { // start Pin from child char **inArgv = new char*[pinArgs->size()+10]; // Pin binary in the first list ::iterator pinArgIt = pinArgs->begin(); string pinBinary = *pinArgIt; pinArgIt++; // build pin arguments: // pin -pid appPid [pinarg] unsigned int idx = 0; inArgv[idx++] = (char *)pinBinary.c_str(); if ("-pinarg" != *pinArgIt) { inArgv[idx++] = (char *)(pinArgIt++)->c_str(); } pinArgIt++; inArgv[idx++] = (char*)"-pid"; inArgv[idx] = (char *)malloc(10); sprintf(inArgv[idx++], "%d", appPid); for (; pinArgIt != pinArgs->end(); pinArgIt++) { inArgv[idx++]= (char *)pinArgIt->c_str(); } inArgv[idx] = 0; execvp(inArgv[0], inArgv); fprintf(stderr, "ERROR: execv %s failed\n", inArgv[0]); exit(1); } else { fprintf(stderr, "ERROR: fork failed\n"); exit(1); } } int main(int argc, char * argv[]) { list pinArgs; volatile FUNPTR pinAttached = PinAttached; ParseCommandLine(argc, argv, &pinArgs); StartPin(&pinArgs); /* Exit in 20 sec */ signal(SIGALRM, ExitOnAlarm); alarm(20); while (!pinAttached()) { sched_yield(); sleep(2); } return 0; }