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.
109 lines
3.4 KiB
109 lines
3.4 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.
|
|
*/
|
|
|
|
/*! @file
|
|
* Application launcher used for testing Pin in attach mode (as opposed to launch mode)
|
|
* It creates a child process (which is the application we want Pin to attach to) and write its process ID
|
|
* to the output which is later used by Pin to attach to it.
|
|
* The difference between this launcher and w_app_launcher.cpp is that this launcher waits for child process to
|
|
* notify it is ready to be attached by Pin (using semaphore). Intended for tests that the attach point the
|
|
* in time is important for them.
|
|
*/
|
|
#define _CRT_SECURE_NO_WARNINGS
|
|
#define _CRT_SECURE_NO_DEPRECATE
|
|
|
|
#include <assert.h>
|
|
#include <Windows.h>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <string>
|
|
|
|
using std::string;
|
|
using std::endl;
|
|
using std::cout;
|
|
using std::cerr;
|
|
using std::ostringstream;
|
|
// launch given application, write application's PID to stdout
|
|
|
|
int main(int argc, char * argv[], char * envp[])
|
|
{
|
|
string cmdLine = "";
|
|
// Build command line
|
|
for(int i = 1; i < argc; i++)
|
|
{
|
|
cmdLine += string(argv[i]);
|
|
if(i != argc - 1)
|
|
{
|
|
cmdLine += string(" ");
|
|
}
|
|
}
|
|
|
|
// Invoke Application
|
|
STARTUPINFO si;
|
|
PROCESS_INFORMATION pi;
|
|
memset(&si, 0, sizeof(si));
|
|
si.cb = sizeof(STARTUPINFO);
|
|
memset(&pi, 0, sizeof(pi));
|
|
|
|
// Create child process suspended in order to get its process ID first (see below why)
|
|
//
|
|
if (!CreateProcess(NULL, (LPSTR)cmdLine.c_str(), NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, &pi))
|
|
{
|
|
cout << "0" << endl;
|
|
cerr << "Failed to create " << cmdLine << endl;
|
|
exit(-1);
|
|
}
|
|
|
|
|
|
//
|
|
// Wait for child process to notify it is ready to be attached by Pin by using the below semaphore.
|
|
//
|
|
|
|
// Create a unique semaphore handle name using the child process ID
|
|
ostringstream stream;
|
|
stream << pi.dwProcessId;
|
|
string semaphoreHandleName = "semaphore_handle_" + stream.str();
|
|
|
|
HANDLE ChildReadySemaphore;
|
|
ChildReadySemaphore = CreateSemaphore(
|
|
NULL, // default security attributes
|
|
0, // initial count
|
|
1, // maximum count
|
|
semaphoreHandleName.c_str()); // unnamed semaphore
|
|
|
|
// Now that the semaphore handle exist we can resume the child process which will
|
|
// use this handle (by using the unique name)
|
|
ResumeThread(pi.hThread);
|
|
|
|
cerr << " Launcher: waiting on " << semaphoreHandleName << endl;
|
|
DWORD waitResult = WaitForSingleObject(
|
|
ChildReadySemaphore, // handle to semaphore
|
|
30000); // wait 30 seconds
|
|
|
|
if (waitResult == WAIT_TIMEOUT)
|
|
{
|
|
cerr << "Error: Child process didn't notify it is ready to be attached by Pin for more than 30 seconds. ";
|
|
return 1;
|
|
}
|
|
assert(waitResult == WAIT_OBJECT_0);
|
|
|
|
cerr << " Launcher: "<< semaphoreHandleName << " was relesed by App" << endl;
|
|
|
|
// Now we can proceed to attach Pin to child process by writing its process ID (will be used by Pin)
|
|
char digitBuffer[64];
|
|
cout << itoa(pi.dwProcessId, digitBuffer, 10);
|
|
|
|
CloseHandle(ChildReadySemaphore);
|
|
|
|
return 0;
|
|
}
|
|
|