mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
Bug 568079: Hook into Eclipse tracing system for native code
After loading the spawner library, call the native method configureNativeTrace() that will query the Eclipse platform for several debug option strings. Change-Id: I031bb2cdc04ba2675913b3b2e320039c28139638 Signed-off-by: Torbjörn Svensson <azoff@svenskalinuxforeningen.se>
This commit is contained in:
parent
09b1f93e7e
commit
1d2946184a
18 changed files with 187 additions and 121 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,4 +1,9 @@
|
|||
org.eclipse.cdt.core.native/debug=false
|
||||
|
||||
org.eclipse.cdt.core.native/debug/spawner=false
|
||||
org.eclipse.cdt.core.native/debug/spawner/details=false
|
||||
org.eclipse.cdt.core.native/debug/spawner/starter=false
|
||||
org.eclipse.cdt.core.native/debug/spawner/read_report=false
|
||||
|
||||
# Used by org.eclipse.cdt.core.win32 fragment
|
||||
org.eclipse.cdt.core.native/debug/win32/registry=false
|
||||
org.eclipse.cdt.core.native/debug/win32/registry=false
|
||||
|
|
|
@ -47,6 +47,14 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise(JNIEnv *
|
|||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor(JNIEnv *, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||
* Method: configureNativeTrace
|
||||
* Signature: (ZZZZ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_configureNativeTrace(JNIEnv *, jclass, jboolean,
|
||||
jboolean, jboolean, jboolean);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -24,18 +24,7 @@
|
|||
#include "exec0.h"
|
||||
#include <org_eclipse_cdt_utils_spawner_Spawner.h>
|
||||
|
||||
static bool isTraceEnabled(void) {
|
||||
static bool initialized = false;
|
||||
static bool enabled = false;
|
||||
|
||||
if (!initialized) {
|
||||
enabled = getenv("TRACE_ORG_ECLIPSE_CDT_SPAWNER") != NULL;
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return enabled;
|
||||
}
|
||||
static bool trace_enabled = false;
|
||||
|
||||
static void print_array(FILE *stream, const char *str, char **c_array) {
|
||||
if (c_array) {
|
||||
|
@ -116,7 +105,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2(JNIEnv *
|
|||
goto bail_out;
|
||||
}
|
||||
|
||||
if (isTraceEnabled()) {
|
||||
if (trace_enabled) {
|
||||
print_array(stderr, "command:", cmd);
|
||||
print_array(stderr, "Envp:", envp);
|
||||
fprintf(stderr, "dirpath: %s\n", dirpath);
|
||||
|
@ -160,7 +149,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1(JNIEnv *
|
|||
goto bail_out;
|
||||
}
|
||||
|
||||
if (isTraceEnabled()) {
|
||||
if (trace_enabled) {
|
||||
print_array(stderr, "command:", cmd);
|
||||
print_array(stderr, "Envp:", envp);
|
||||
fprintf(stderr, "dirpath: %s\n", dirpath);
|
||||
|
@ -213,7 +202,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0(JNIEnv *
|
|||
goto bail_out;
|
||||
}
|
||||
|
||||
if (isTraceEnabled()) {
|
||||
if (trace_enabled) {
|
||||
print_array(stderr, "command:", cmd);
|
||||
print_array(stderr, "Envp:", envp);
|
||||
fprintf(stderr, "dirpath: %s\n", dirpath);
|
||||
|
@ -235,11 +224,6 @@ bail_out:
|
|||
return pid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||
* Method: raise
|
||||
* Signature: (II)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise(JNIEnv *env, jobject jobj, jint pid, jint sig) {
|
||||
int status = -1;
|
||||
|
||||
|
@ -283,11 +267,13 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise(JNIEnv *
|
|||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||
* Method: waitFor
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor(JNIEnv *env, jobject jobj, jint pid) {
|
||||
return wait0(pid);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_configureNativeTrace(
|
||||
JNIEnv *env, jclass cls, jboolean spawner, jboolean spawnerDetails, jboolean starter, jboolean readReport) {
|
||||
if (spawner) {
|
||||
trace_enabled = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include "util.h"
|
||||
|
||||
#include "org_eclipse_cdt_utils_spawner_Spawner.h"
|
||||
#include <org_eclipse_cdt_utils_spawner_Spawner.h>
|
||||
|
||||
#define PIPE_SIZE 512 // Size of pipe buffer
|
||||
#define MAX_CMD_SIZE 2049 // Initial size of command line
|
||||
|
@ -133,7 +133,7 @@ static bool createStandardNamedPipe(HANDLE *handle, DWORD stdHandle, int pid, in
|
|||
dwOpenMode = PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED;
|
||||
break;
|
||||
default:
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Invalid STD handle given %i", stdHandle);
|
||||
}
|
||||
return false;
|
||||
|
@ -142,7 +142,7 @@ static bool createStandardNamedPipe(HANDLE *handle, DWORD stdHandle, int pid, in
|
|||
HANDLE pipe = CreateNamedPipeW(pipeName, dwOpenMode, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
|
||||
PIPE_UNLIMITED_INSTANCES, PIPE_SIZE, PIPE_SIZE, PIPE_TIMEOUT, NULL);
|
||||
if (INVALID_HANDLE_VALUE == pipe) {
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Failed to create named pipe: %s\n", pipeName);
|
||||
}
|
||||
return false;
|
||||
|
@ -150,7 +150,7 @@ static bool createStandardNamedPipe(HANDLE *handle, DWORD stdHandle, int pid, in
|
|||
|
||||
SetHandleInformation(pipe, HANDLE_FLAG_INHERIT, TRUE);
|
||||
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Successfully created pipe %s -> %p\n", pipeName, pipe);
|
||||
}
|
||||
|
||||
|
@ -164,12 +164,12 @@ static bool createNamedEvent(EventInfo_t *eventInfo, BOOL manualReset, const wch
|
|||
|
||||
HANDLE event = CreateEventW(NULL, manualReset, FALSE, eventName);
|
||||
if (!event) {
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Failed to create event %s -> %i\n", eventName, GetLastError());
|
||||
}
|
||||
return false;
|
||||
} else if (GetLastError() == ERROR_ALREADY_EXISTS) {
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Event %s already exist -> %p\n", eventName, event);
|
||||
}
|
||||
return false;
|
||||
|
@ -179,13 +179,13 @@ static bool createNamedEvent(EventInfo_t *eventInfo, BOOL manualReset, const wch
|
|||
eventInfo->name = wcsdup(eventName);
|
||||
|
||||
if (!eventInfo->name) {
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Failed to allocate memory for event %s -> %p\n", eventName, event);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Successfully created event %s -> %p\n", eventName, event);
|
||||
}
|
||||
|
||||
|
@ -282,7 +282,7 @@ static bool createCommandLine(JNIEnv *env, jobjectArray cmdarray, wchar_t **cmdL
|
|||
static bool createEnvironmentBlock(JNIEnv *env, jobjectArray envp, wchar_t **block) {
|
||||
int nEnvVars = (*env)->GetArrayLength(env, envp);
|
||||
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"There are %i environment variables \n", nEnvVars);
|
||||
}
|
||||
|
||||
|
@ -292,36 +292,39 @@ static bool createEnvironmentBlock(JNIEnv *env, jobjectArray envp, wchar_t **blo
|
|||
}
|
||||
|
||||
int nPos = 0;
|
||||
int nBlkSize = MAX_ENV_SIZE;
|
||||
wchar_t *buffer = (wchar_t *)malloc(nBlkSize * sizeof(wchar_t));
|
||||
int bufferSize = MAX_ENV_SIZE;
|
||||
wchar_t *buffer = (wchar_t *)malloc(bufferSize * sizeof(wchar_t));
|
||||
for (int i = 0; i < nEnvVars; ++i) {
|
||||
jstring item = (jstring)(*env)->GetObjectArrayElement(env, envp, i);
|
||||
jsize len = (*env)->GetStringLength(env, item);
|
||||
const jchar *str = (*env)->GetStringChars(env, item, 0);
|
||||
if (str) {
|
||||
while (nBlkSize - nPos <= len + 2) { // +2 for two '\0'
|
||||
nBlkSize += MAX_ENV_SIZE;
|
||||
wchar_t *tmp = (wchar_t *)realloc(buffer, nBlkSize * sizeof(wchar_t));
|
||||
int len = wcslen(str);
|
||||
while (bufferSize - nPos <= len + 2) { // +2 for two '\0'
|
||||
bufferSize += MAX_ENV_SIZE;
|
||||
wchar_t *tmp = (wchar_t *)realloc(buffer, bufferSize * sizeof(wchar_t));
|
||||
if (tmp) {
|
||||
buffer = tmp;
|
||||
} else {
|
||||
free(buffer);
|
||||
(*env)->ReleaseStringChars(env, item, str);
|
||||
ThrowByName(env, "java/io/IOException", "Not enough memory");
|
||||
return false;
|
||||
}
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Realloc environment block; new length is %i \n", nBlkSize);
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Realloc environment block; new length is %i \n", bufferSize);
|
||||
}
|
||||
}
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"%s\n", (const wchar_t *)str);
|
||||
}
|
||||
wcsncpy(buffer + nPos, (const wchar_t *)str, len);
|
||||
wcsncpy(buffer + nPos, str, len);
|
||||
nPos += len;
|
||||
buffer[nPos++] = _T('\0');
|
||||
|
||||
(*env)->ReleaseStringChars(env, item, str);
|
||||
}
|
||||
}
|
||||
|
||||
buffer[nPos] = _T('\0');
|
||||
*block = buffer;
|
||||
|
||||
|
@ -398,14 +401,15 @@ extern "C"
|
|||
|
||||
// Prepare command line
|
||||
wchar_t *cmdLine = NULL;
|
||||
if (!createCommandLine(env, cmdarray, &cmdLine, L"\"%sstarter.exe\" %i %i %s %s %s %s %s ", path, //
|
||||
pid, //
|
||||
nLocalCounter, //
|
||||
pCurProcInfo->eventBreak.name, //
|
||||
pCurProcInfo->eventWait.name, //
|
||||
pCurProcInfo->eventTerminate.name, //
|
||||
pCurProcInfo->eventKill.name, //
|
||||
pCurProcInfo->eventCtrlc.name)) {
|
||||
if (!createCommandLine(env, cmdarray, &cmdLine, L"\"%sstarter.exe\" %i %i %s %s %s %s %s %i ", path, //
|
||||
pid, //
|
||||
nLocalCounter, //
|
||||
pCurProcInfo->eventBreak.name, //
|
||||
pCurProcInfo->eventWait.name, //
|
||||
pCurProcInfo->eventTerminate.name, //
|
||||
pCurProcInfo->eventKill.name, //
|
||||
pCurProcInfo->eventCtrlc.name, //
|
||||
isTraceEnabled(CDT_TRACE_SPAWNER_STARTER))) {
|
||||
// Exception already thrown, just clean up
|
||||
cleanUpProcBlock(pCurProcInfo);
|
||||
CLOSE_HANDLES(stdHandles);
|
||||
|
@ -441,7 +445,7 @@ extern "C"
|
|||
flags |= CREATE_NO_WINDOW;
|
||||
flags |= CREATE_UNICODE_ENVIRONMENT;
|
||||
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(cmdLine);
|
||||
}
|
||||
|
||||
|
@ -474,13 +478,13 @@ extern "C"
|
|||
|
||||
int what = WaitForMultipleObjects(2, h, FALSE, INFINITE);
|
||||
if (what != WAIT_OBJECT_0) { // CreateProcess failed
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Process %i failed\n", pi.dwProcessId);
|
||||
}
|
||||
cleanUpProcBlock(pCurProcInfo);
|
||||
CLOSE_HANDLES(stdHandles);
|
||||
ThrowByName(env, "java/io/IOException", "Launching failed");
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Process failed\n");
|
||||
}
|
||||
} else {
|
||||
|
@ -498,7 +502,7 @@ extern "C"
|
|||
memcpy(piCopy, &pi, sizeof(PROCESS_INFORMATION));
|
||||
_beginthread(waitProcTermination, 0, (void *)piCopy);
|
||||
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Process started\n");
|
||||
}
|
||||
}
|
||||
|
@ -624,7 +628,7 @@ extern "C"
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Spawner received signal %i for process %i\n", signal, pCurProcInfo->pid);
|
||||
}
|
||||
|
||||
|
@ -644,22 +648,22 @@ extern "C"
|
|||
ret = 0;
|
||||
break;
|
||||
case SIG_TERM:
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Spawner received TERM signal for process %i\n", pCurProcInfo->pid);
|
||||
}
|
||||
SetEvent(pCurProcInfo->eventTerminate.handle);
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Spawner signaled TERM event\n");
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case SIG_KILL:
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Spawner received KILL signal for process %i\n", pCurProcInfo->pid);
|
||||
}
|
||||
SetEvent(pCurProcInfo->eventKill.handle);
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Spawner signaled KILL event\n");
|
||||
}
|
||||
ret = 0;
|
||||
|
@ -825,7 +829,7 @@ void _cdecl waitProcTermination(void *pv) {
|
|||
for (int i = 0; i < MAX_PROCS; i++) {
|
||||
if (pInfo[i].pid == pi->dwProcessId) {
|
||||
cleanUpProcBlock(pInfo + i);
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"waitProcTermination: set PID %i to 0\n", pi->dwProcessId);
|
||||
}
|
||||
}
|
||||
|
@ -834,3 +838,28 @@ void _cdecl waitProcTermination(void *pv) {
|
|||
|
||||
free(pi);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_eclipse_cdt_utils_spawner_Spawner_configureNativeTrace(JNIEnv *env, jclass cls, jboolean spawner,
|
||||
jboolean spawnerDetails, jboolean starter,
|
||||
jboolean readReport) {
|
||||
|
||||
if (spawner) {
|
||||
enableTraceFor(CDT_TRACE_SPAWNER);
|
||||
}
|
||||
|
||||
if (spawnerDetails) {
|
||||
enableTraceFor(CDT_TRACE_SPAWNER_DETAILS);
|
||||
}
|
||||
|
||||
if (starter) {
|
||||
enableTraceFor(CDT_TRACE_SPAWNER_STARTER);
|
||||
}
|
||||
|
||||
if (readReport) {
|
||||
enableTraceFor(CDT_TRACE_SPAWNER_READ_REPORT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "util.h"
|
||||
|
||||
#include "org_eclipse_cdt_utils_spawner_Spawner.h"
|
||||
#include <org_eclipse_cdt_utils_spawner_Spawner.h>
|
||||
|
||||
void ThrowByName(JNIEnv *env, const char *name, const char *msg);
|
||||
|
||||
|
@ -80,7 +80,7 @@ extern "C"
|
|||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR) && isTraceEnabled(CDT_TRACE_READ_REPORT)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER) && isTraceEnabled(CDT_TRACE_SPAWNER_READ_REPORT)) {
|
||||
cdtTrace(L"Start read %p\n", handle);
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ extern "C"
|
|||
}
|
||||
if (err != 0) {
|
||||
char *lpMsgBuf;
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Read failed - %p, error %i\n", handle, err);
|
||||
}
|
||||
if (err !=
|
||||
|
@ -121,7 +121,7 @@ extern "C"
|
|||
} else {
|
||||
// buffer overflow?
|
||||
// according to msdn this happens in message read mode only
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Buffer full - %p, bytes read: %i\n", handle, nNumberOfBytesRead);
|
||||
}
|
||||
// nNumberOfBytesRead can be 0 here for unknown reason (bug 269223)
|
||||
|
@ -147,7 +147,7 @@ extern "C"
|
|||
}
|
||||
}
|
||||
CloseHandle(overlapped.hEvent);
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR) && isTraceEnabled(CDT_TRACE_READ_REPORT)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER) && isTraceEnabled(CDT_TRACE_SPAWNER_READ_REPORT)) {
|
||||
cdtTrace(L"End read %p - bytes read: %d\n", handle, nBuffOffset);
|
||||
}
|
||||
return nBuffOffset; // This is a real full readed length
|
||||
|
@ -160,11 +160,11 @@ extern "C"
|
|||
Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_close0(JNIEnv *env, jobject proc, jobject channel) {
|
||||
int rc;
|
||||
HANDLE handle = channelToHandle(env, channel);
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Close %p\n", handle);
|
||||
}
|
||||
rc = (CloseHandle(handle) ? 0 : -1);
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Closed %p\n", handle);
|
||||
}
|
||||
return (rc ? GetLastError() : 0);
|
||||
|
@ -221,12 +221,12 @@ extern "C"
|
|||
Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_close0(JNIEnv *env, jobject proc, jobject channel) {
|
||||
int rc;
|
||||
HANDLE handle = channelToHandle(env, channel);
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Close %p\n", handle);
|
||||
}
|
||||
FlushFileBuffers(handle);
|
||||
rc = (CloseHandle(handle) ? 0 : -1);
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Closed %p\n", handle);
|
||||
}
|
||||
return (rc ? GetLastError() : 0);
|
||||
|
|
|
@ -20,9 +20,7 @@
|
|||
|
||||
#include "util.h"
|
||||
|
||||
#include "org_eclipse_cdt_utils_spawner_Spawner.h"
|
||||
|
||||
extern void JNICALL ThrowByName(JNIEnv *env, const char *name, const char *msg);
|
||||
#include <org_eclipse_cdt_utils_spawner_Spawner.h>
|
||||
|
||||
static HWND consoleHWND;
|
||||
|
||||
|
@ -97,7 +95,7 @@ int interruptProcess(int pid) {
|
|||
int rc = 0;
|
||||
consoleHWND = NULL;
|
||||
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Try to interrupt process %i\n", pid);
|
||||
}
|
||||
// Find console
|
||||
|
@ -155,11 +153,11 @@ int interruptProcess(int pid) {
|
|||
if (child_thread) {
|
||||
AttachThreadInput(GetCurrentThreadId(), child_thread, FALSE);
|
||||
}
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Sent Ctrl-C & Ctrl-Break to process %i\n", pid);
|
||||
}
|
||||
}
|
||||
} else if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
} else if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Cannot find console for process %i\n", pid);
|
||||
}
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ static bool openNamedPipeAsStdHandle(HANDLE *handle, DWORD stdHandle, int parent
|
|||
dwShareMode = FILE_SHARE_WRITE;
|
||||
break;
|
||||
default:
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Invalid STD handle given %i", stdHandle);
|
||||
}
|
||||
return false;
|
||||
|
@ -151,7 +151,7 @@ static bool openNamedPipeAsStdHandle(HANDLE *handle, DWORD stdHandle, int parent
|
|||
|
||||
*handle = CreateFileW(pipeName, dwDesiredAccess, dwShareMode, NULL, OPEN_EXISTING, 0, sa);
|
||||
if (INVALID_HANDLE_VALUE == *handle) {
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Failed to open pipe: %s -> %p\n", pipeName, handle);
|
||||
}
|
||||
return false;
|
||||
|
@ -160,13 +160,13 @@ static bool openNamedPipeAsStdHandle(HANDLE *handle, DWORD stdHandle, int parent
|
|||
SetHandleInformation(*handle, HANDLE_FLAG_INHERIT, TRUE);
|
||||
|
||||
if (!SetStdHandle(stdHandle, *handle)) {
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Failed to reassign standard stream to pipe %s: %i\n", pipeName, GetLastError());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Successfully assigned pipe %s -> %p\n", pipeName, *handle);
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,7 @@ bool createCommandLine(int argc, wchar_t **argv, wchar_t **cmdLine) {
|
|||
int required = nPos + len + 2; // 2 => space + \0
|
||||
if (required > 32 * 1024) {
|
||||
free(buffer);
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Command line too long!\n");
|
||||
}
|
||||
return false;
|
||||
|
@ -212,7 +212,7 @@ bool createCommandLine(int argc, wchar_t **argv, wchar_t **cmdLine) {
|
|||
} else {
|
||||
// Failed to realloc memory
|
||||
free(buffer);
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Not enough memory to build cmd line!\n");
|
||||
}
|
||||
return false;
|
||||
|
@ -235,7 +235,7 @@ bool createCommandLine(int argc, wchar_t **argv, wchar_t **cmdLine) {
|
|||
buffer[nPos] = _T('\0');
|
||||
} else {
|
||||
free(buffer);
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Invalid argument!\n");
|
||||
}
|
||||
return false;
|
||||
|
@ -252,11 +252,20 @@ int main() {
|
|||
wchar_t **argv = CommandLineToArgvW(GetCommandLine(), &argc);
|
||||
|
||||
// Make sure that we've been passed the right number of arguments
|
||||
if (argc < 8) {
|
||||
wprintf(L"Usage: %s (parent pid) (counter) (four inheritable event handles) (CommandLineToSpawn)\n", argv[0]);
|
||||
if (argc < 9) {
|
||||
wprintf(
|
||||
L"Usage: %s (parent pid) (counter) (four inheritable event handles) (trace enable) (CommandLineToSpawn)\n",
|
||||
argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Activate tracing...
|
||||
if (wcstol(argv[8], NULL, 2)) {
|
||||
for (int i = 0; i < sizeof(ALL_TRACE_KINDS) / sizeof(ALL_TRACE_KINDS[0]); i++) {
|
||||
enableTraceFor(ALL_TRACE_KINDS[i]);
|
||||
}
|
||||
}
|
||||
|
||||
STARTUPINFOW si = {sizeof(si)};
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
DWORD dwExitCode = 0;
|
||||
|
@ -293,7 +302,7 @@ int main() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR_DETAILS)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER_DETAILS)) {
|
||||
wchar_t *lpvEnv = GetEnvironmentStringsW();
|
||||
|
||||
if (lpvEnv) {
|
||||
|
@ -322,23 +331,23 @@ int main() {
|
|||
ZeroMemory(&jobInfo, sizeof(jobInfo));
|
||||
jobInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_BREAKAWAY_OK;
|
||||
if (!SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &jobInfo, sizeof(jobInfo))) {
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Cannot set job information\n");
|
||||
DisplayErrorMessage();
|
||||
}
|
||||
}
|
||||
} else if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
} else if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Cannot create job object\n");
|
||||
DisplayErrorMessage();
|
||||
}
|
||||
|
||||
// Construct the full command line
|
||||
wchar_t *cmdLine = NULL;
|
||||
if (!createCommandLine(argc - 8, &argv[8], &cmdLine)) {
|
||||
if (!createCommandLine(argc - 9, &argv[9], &cmdLine)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Starting: %s\n", cmdLine);
|
||||
}
|
||||
|
||||
|
@ -359,7 +368,7 @@ int main() {
|
|||
free(cmdLine);
|
||||
cmdLine = NULL;
|
||||
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Process %i started\n", pi.dwProcessId);
|
||||
}
|
||||
SetEvent(waitEvent); // Means that process has been spawned
|
||||
|
@ -368,7 +377,7 @@ int main() {
|
|||
|
||||
if (hJob) {
|
||||
if (!AssignProcessToJobObject(hJob, pi.hProcess)) {
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Cannot assign process %i to a job\n", pi.dwProcessId);
|
||||
DisplayErrorMessage();
|
||||
}
|
||||
|
@ -382,7 +391,7 @@ int main() {
|
|||
switch (event) {
|
||||
case WAIT_OBJECT_0 + 0: // SIGINT
|
||||
case WAIT_OBJECT_0 + 4: // CTRL-C
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"starter (PID %i) received CTRL-C event\n", GetCurrentProcessId());
|
||||
}
|
||||
if ((event == (WAIT_OBJECT_0 + 0)) && isCygwin(h[1])) {
|
||||
|
@ -402,7 +411,7 @@ int main() {
|
|||
|
||||
case WAIT_OBJECT_0 + 1: // App terminated normally
|
||||
// Make it's exit code our exit code
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"starter: launched process has been terminated(PID %i)\n", pi.dwProcessId);
|
||||
}
|
||||
GetExitCodeProcess(pi.hProcess, &dwExitCode);
|
||||
|
@ -417,7 +426,7 @@ int main() {
|
|||
case WAIT_OBJECT_0 + 3: // KILL
|
||||
{
|
||||
const wchar_t *signal = (event == WAIT_OBJECT_0 + 2) ? L"TERM" : L"KILL";
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"starter received %s event (PID %i)\n", signal, GetCurrentProcessId());
|
||||
}
|
||||
if (isCygwin(h[1])) {
|
||||
|
@ -436,7 +445,7 @@ int main() {
|
|||
|
||||
if (hJob) {
|
||||
if (!TerminateJobObject(hJob, (DWORD)-1)) {
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Cannot terminate job\n");
|
||||
DisplayErrorMessage();
|
||||
}
|
||||
|
@ -449,14 +458,14 @@ int main() {
|
|||
|
||||
default:
|
||||
// Unexpected code
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
DisplayErrorMessage();
|
||||
}
|
||||
exitProc = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
} else if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
|
||||
cdtTrace(L"Cannot start: %s\n", cmdLine);
|
||||
free(cmdLine);
|
||||
|
||||
|
@ -478,5 +487,4 @@ void DisplayErrorMessage() {
|
|||
// Free the buffer.
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
|
||||
//////////////////////////////// End of File //////////////////////////////////
|
||||
|
|
|
@ -17,29 +17,43 @@
|
|||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
|
||||
bool isTraceEnabled(const TraceKind_t traceKind) {
|
||||
static bool initialized = false;
|
||||
static bool monitor = false;
|
||||
static bool monitorDetails = false;
|
||||
static bool readReport = false;
|
||||
|
||||
if (!initialized) {
|
||||
monitor = _wgetenv(L"TRACE_ORG_ECLIPSE_CDT_MONITOR") != NULL;
|
||||
monitorDetails = _wgetenv(L"TRACE_ORG_ECLIPSE_CDT_MONITORDETAILS") != NULL;
|
||||
readReport = _wgetenv(L"TRACE_ORG_ECLIPSE_CDT_READREPORT") != NULL;
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
static bool spawner = false;
|
||||
static bool spawnerDetails = false;
|
||||
static bool spawnerStarter = false;
|
||||
static bool readReport = false;
|
||||
|
||||
void enableTraceFor(const TraceKind_t traceKind) {
|
||||
switch (traceKind) {
|
||||
case CDT_TRACE_MONITOR:
|
||||
return monitor;
|
||||
case CDT_TRACE_MONITOR_DETAILS:
|
||||
return monitorDetails;
|
||||
case CDT_TRACE_READ_REPORT:
|
||||
case CDT_TRACE_SPAWNER:
|
||||
spawner = true;
|
||||
break;
|
||||
case CDT_TRACE_SPAWNER_DETAILS:
|
||||
spawnerDetails = true;
|
||||
break;
|
||||
case CDT_TRACE_SPAWNER_STARTER:
|
||||
spawnerStarter = true;
|
||||
break;
|
||||
case CDT_TRACE_SPAWNER_READ_REPORT:
|
||||
readReport = true;
|
||||
break;
|
||||
default:
|
||||
cdtTrace(L"%S: Invalid trace kind supplied: %d\n", __func__, traceKind);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool isTraceEnabled(const TraceKind_t traceKind) {
|
||||
switch (traceKind) {
|
||||
case CDT_TRACE_SPAWNER:
|
||||
return spawner;
|
||||
case CDT_TRACE_SPAWNER_DETAILS:
|
||||
return spawnerDetails;
|
||||
case CDT_TRACE_SPAWNER_STARTER:
|
||||
return spawnerStarter;
|
||||
case CDT_TRACE_SPAWNER_READ_REPORT:
|
||||
return readReport;
|
||||
default:
|
||||
cdtTrace(L"Invalid trace kind supplied: %d\n", traceKind);
|
||||
cdtTrace(L"%S: Invalid trace kind supplied: %d\n", __func__, traceKind);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,16 @@
|
|||
#include <stdbool.h>
|
||||
#include <windows.h>
|
||||
|
||||
typedef enum { CDT_TRACE_MONITOR, CDT_TRACE_MONITOR_DETAILS, CDT_TRACE_READ_REPORT } TraceKind_t;
|
||||
typedef enum {
|
||||
CDT_TRACE_SPAWNER,
|
||||
CDT_TRACE_SPAWNER_DETAILS,
|
||||
CDT_TRACE_SPAWNER_STARTER,
|
||||
CDT_TRACE_SPAWNER_READ_REPORT
|
||||
} TraceKind_t;
|
||||
static const TraceKind_t ALL_TRACE_KINDS[] = {CDT_TRACE_SPAWNER, CDT_TRACE_SPAWNER_DETAILS, CDT_TRACE_SPAWNER_STARTER,
|
||||
CDT_TRACE_SPAWNER_READ_REPORT};
|
||||
|
||||
void enableTraceFor(const TraceKind_t traceKind);
|
||||
bool isTraceEnabled(const TraceKind_t traceKind);
|
||||
void cdtTrace(const wchar_t *fmt, ...);
|
||||
|
||||
|
|
|
@ -457,6 +457,10 @@ public class Spawner extends Process {
|
|||
static {
|
||||
try {
|
||||
System.loadLibrary("spawner"); //$NON-NLS-1$
|
||||
configureNativeTrace(Platform.getDebugBoolean(CNativePlugin.PLUGIN_ID + "/debug/spawner"), //$NON-NLS-1$
|
||||
Platform.getDebugBoolean(CNativePlugin.PLUGIN_ID + "/debug/spawner/details"), //$NON-NLS-1$
|
||||
Platform.getDebugBoolean(CNativePlugin.PLUGIN_ID + "/debug/spawner/starter"), //$NON-NLS-1$
|
||||
Platform.getDebugBoolean(CNativePlugin.PLUGIN_ID + "/debug/spawner/read_report")); //$NON-NLS-1$
|
||||
} catch (SecurityException e) {
|
||||
CNativePlugin.log(e);
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
|
@ -464,6 +468,12 @@ public class Spawner extends Process {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 6.0
|
||||
*/
|
||||
private static native void configureNativeTrace(boolean spawner, boolean spawnerDetails, boolean starter,
|
||||
boolean readReport);
|
||||
|
||||
/**
|
||||
* @since 6.0
|
||||
*/
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Add table
Reference in a new issue