mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-21 21:52:10 +02:00
Bug 568079: Do not require rebuild of natives to enable/disable tracing
Change-Id: I6e26c6febd56bcc23efe0ec65973b2f02a5fd809 Signed-off-by: Torbjörn Svensson <azoff@svenskalinuxforeningen.se>
This commit is contained in:
parent
b0d25c22eb
commit
2857a7a0b3
16 changed files with 302 additions and 254 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -72,7 +72,7 @@ rebuild: clean all
|
|||
# However, x86_64-w64-mingw32-ld on Debian/Ubuntu has a patch that overrides the current date
|
||||
# using the SOURCE_DATE_EPOCH environment variable. Call REPRODUCIBLE_BUILD_WRAPPER to make sure the
|
||||
# same binary is produced for the same source each time.
|
||||
$(OS_DIR_WIN32_X86_64)/starter.exe: win/starter.c
|
||||
$(OS_DIR_WIN32_X86_64)/starter.exe: win/starter.c win/util.c
|
||||
mkdir -p $(dir $@) && \
|
||||
$(REPRODUCIBLE_BUILD_WRAPPER) \
|
||||
x86_64-w64-mingw32-gcc $(COMMON_CFLAGS) -o $@ -Iinclude -I"$(JAVA_HOME)/include" -I"$(JAVA_HOME)/include/win32" \
|
||||
|
@ -80,7 +80,7 @@ $(OS_DIR_WIN32_X86_64)/starter.exe: win/starter.c
|
|||
$^ \
|
||||
-lpsapi
|
||||
|
||||
$(OS_DIR_WIN32_X86_64)/spawner.dll: win/iostream.c win/raise.c win/spawner.c win/Win32ProcessEx.c
|
||||
$(OS_DIR_WIN32_X86_64)/spawner.dll: win/iostream.c win/raise.c win/spawner.c win/Win32ProcessEx.c win/util.c
|
||||
mkdir -p $(dir $@) && \
|
||||
$(REPRODUCIBLE_BUILD_WRAPPER) \
|
||||
x86_64-w64-mingw32-gcc $(COMMON_CFLAGS) -o $@ -Iinclude -I"$(JAVA_HOME)/include" -I"$(JAVA_HOME)/include/win32" \
|
||||
|
@ -88,7 +88,7 @@ $(OS_DIR_WIN32_X86_64)/spawner.dll: win/iostream.c win/raise.c win/spawner.c win
|
|||
$^ \
|
||||
-Wl,--kill-at --shared
|
||||
|
||||
$(OS_DIR_WIN32_X86_64)/pty.dll: win/pty.cpp win/pty_dllmain.cpp
|
||||
$(OS_DIR_WIN32_X86_64)/pty.dll: win/pty.cpp win/pty_dllmain.cpp win/util.c
|
||||
mkdir -p $(dir $@) && \
|
||||
$(REPRODUCIBLE_BUILD_WRAPPER) \
|
||||
x86_64-w64-mingw32-g++ $(COMMON_CFLAGS) -o $@ -Iinclude -Iwin/include -I"$(JAVA_HOME)/include" -I"$(JAVA_HOME)/include/win32" \
|
||||
|
|
|
@ -19,33 +19,51 @@
|
|||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <jni.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "exec0.h"
|
||||
#include <org_eclipse_cdt_utils_spawner_Spawner.h>
|
||||
|
||||
#define DEBUGIT 0
|
||||
static bool isTraceEnabled(void) {
|
||||
static bool initialized = false;
|
||||
static bool enabled = false;
|
||||
|
||||
/*
|
||||
* Header for class org_eclipse_cdt_utils_spawner_Spawner
|
||||
*/
|
||||
if (!initialized) {
|
||||
enabled = getenv("TRACE_ORG_ECLIPSE_CDT_SPAWNER") != NULL;
|
||||
|
||||
#if DEBUGIT
|
||||
static void print_array(char **c_array) {
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
static void print_array(FILE *stream, const char *str, char **c_array) {
|
||||
if (c_array) {
|
||||
bool hasElement = false;
|
||||
|
||||
fprintf(stream, "%s [", str);
|
||||
|
||||
for (char **p = c_array; *p; p++) {
|
||||
if (*p) {
|
||||
fprintf(stderr, " %s", *p);
|
||||
if (hasElement) {
|
||||
fprintf(stream, ",");
|
||||
}
|
||||
hasElement = true;
|
||||
fprintf(stream, "\n \"%s\"", *p);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasElement) {
|
||||
fprintf(stream, "\n");
|
||||
}
|
||||
|
||||
fprintf(stream, "]\n");
|
||||
} else {
|
||||
fprintf(stderr, "null");
|
||||
fprintf(stream, "%s null\n", str);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static char **alloc_c_array(JNIEnv *env, jobjectArray j_array) {
|
||||
int i;
|
||||
jint c_array_size = (*env)->GetArrayLength(env, j_array);
|
||||
char **c_array = calloc(c_array_size + 1, sizeof(char *));
|
||||
|
||||
|
@ -53,7 +71,7 @@ static char **alloc_c_array(JNIEnv *env, jobjectArray j_array) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < c_array_size; i++) {
|
||||
for (int i = 0; i < c_array_size; i++) {
|
||||
jstring j_str = (jstring)(*env)->GetObjectArrayElement(env, j_array, i);
|
||||
const char *c_str = (*env)->GetStringUTFChars(env, j_str, NULL);
|
||||
c_array[i] = (char *)strdup(c_str);
|
||||
|
@ -98,14 +116,12 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2(JNIEnv *
|
|||
goto bail_out;
|
||||
}
|
||||
|
||||
#if DEBUGIT
|
||||
fprintf(stderr, "command:");
|
||||
print_array(cmd);
|
||||
fprintf(stderr, "Envp:");
|
||||
print_array(envp);
|
||||
fprintf(stderr, "dirpath: %s\n", dirpath);
|
||||
fprintf(stderr, "pts_name: %s\n", pts_name);
|
||||
#endif
|
||||
if (isTraceEnabled()) {
|
||||
print_array(stderr, "command:", cmd);
|
||||
print_array(stderr, "Envp:", envp);
|
||||
fprintf(stderr, "dirpath: %s\n", dirpath);
|
||||
fprintf(stderr, "pts_name: %s\n", pts_name);
|
||||
}
|
||||
|
||||
pid = exec_pty(cmd[0], cmd, envp, dirpath, fd, pts_name, masterFD, console);
|
||||
if (pid < 0) {
|
||||
|
@ -144,13 +160,11 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1(JNIEnv *
|
|||
goto bail_out;
|
||||
}
|
||||
|
||||
#if DEBUGIT
|
||||
fprintf(stderr, "command:");
|
||||
print_array(cmd);
|
||||
fprintf(stderr, "Envp:");
|
||||
print_array(envp);
|
||||
fprintf(stderr, "dirpath: %s\n", dirpath);
|
||||
#endif
|
||||
if (isTraceEnabled()) {
|
||||
print_array(stderr, "command:", cmd);
|
||||
print_array(stderr, "Envp:", envp);
|
||||
fprintf(stderr, "dirpath: %s\n", dirpath);
|
||||
}
|
||||
|
||||
pid = exec0(cmd[0], cmd, envp, dirpath, NULL);
|
||||
if (pid < 0) {
|
||||
|
@ -199,13 +213,11 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0(JNIEnv *
|
|||
goto bail_out;
|
||||
}
|
||||
|
||||
#if DEBUGIT
|
||||
fprintf(stderr, "command:");
|
||||
print_array(cmd);
|
||||
fprintf(stderr, "Envp:");
|
||||
print_array(envp);
|
||||
fprintf(stderr, "dirpath: %s\n", dirpath);
|
||||
#endif
|
||||
if (isTraceEnabled()) {
|
||||
print_array(stderr, "command:", cmd);
|
||||
print_array(stderr, "Envp:", envp);
|
||||
fprintf(stderr, "dirpath: %s\n", dirpath);
|
||||
}
|
||||
pid = exec0(cmd[0], cmd, envp, dirpath, fd);
|
||||
if (pid < 0) {
|
||||
goto bail_out;
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <windows.h>
|
||||
#include <jni.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#include "org_eclipse_cdt_utils_spawner_Spawner.h"
|
||||
|
||||
#define PIPE_SIZE 512 // Size of pipe buffer
|
||||
|
@ -159,9 +161,6 @@ extern "C"
|
|||
wchar_t eventTerminateName[MAX_EVENT_NAME_LENGTH];
|
||||
wchar_t eventKillName[MAX_EVENT_NAME_LENGTH];
|
||||
wchar_t eventCtrlcName[MAX_EVENT_NAME_LENGTH];
|
||||
#ifdef DEBUG_MONITOR
|
||||
wchar_t buffer[4000];
|
||||
#endif
|
||||
int nLocalCounter;
|
||||
wchar_t inPipeName[PIPE_NAME_LENGTH];
|
||||
wchar_t outPipeName[PIPE_NAME_LENGTH];
|
||||
|
@ -228,11 +227,9 @@ extern "C"
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("Opened pipes: %s, %s, %s\n"), inPipeName, outPipeName,
|
||||
errPipeName);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Opened pipes: %s, %s, %s\n", inPipeName, outPipeName, errPipeName);
|
||||
}
|
||||
|
||||
nCmdTokens = (*env)->GetArrayLength(env, cmdarray);
|
||||
nEnvVars = (*env)->GetArrayLength(env, envp);
|
||||
|
@ -298,10 +295,10 @@ extern "C"
|
|||
}
|
||||
szCmdLine[nPos] = _T('\0');
|
||||
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("There are %i environment variables \n"), nEnvVars);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"There are %i environment variables \n", nEnvVars);
|
||||
}
|
||||
|
||||
// Prepare environment block
|
||||
if (nEnvVars > 0) {
|
||||
nPos = 0;
|
||||
|
@ -318,16 +315,13 @@ extern "C"
|
|||
ThrowByName(env, "java/io/IOException", "Not enough memory");
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]),
|
||||
_T("Realloc environment block; new length is %i \n"), nBlkSize);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Realloc environment block; new length is %i \n", nBlkSize);
|
||||
}
|
||||
}
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"%s\n", str);
|
||||
}
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("%s\n"), str);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
wcsncpy(szEnvBlock + nPos, str, len);
|
||||
nPos += len;
|
||||
szEnvBlock[nPos] = _T('\0');
|
||||
|
@ -359,9 +353,9 @@ extern "C"
|
|||
flags |= CREATE_NO_WINDOW;
|
||||
flags |= CREATE_UNICODE_ENVIRONMENT;
|
||||
|
||||
#ifdef DEBUG_MONITOR
|
||||
OutputDebugStringW(szCmdLine);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(szCmdLine);
|
||||
}
|
||||
// launches starter; we need it to create another console group to correctly process
|
||||
// emulation of SYSint signal (Ctrl-C)
|
||||
ret = CreateProcessW(0, /* executable name */
|
||||
|
@ -404,15 +398,14 @@ extern "C"
|
|||
|
||||
what = WaitForMultipleObjects(2, h, FALSE, INFINITE);
|
||||
if (what != WAIT_OBJECT_0) { // CreateProcess failed
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("Process %i failed\n"), pi.dwProcessId);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Process %i failed\n", pi.dwProcessId);
|
||||
}
|
||||
cleanUpProcBlock(pCurProcInfo);
|
||||
ThrowByName(env, "java/io/IOException", "Launching failed");
|
||||
#ifdef DEBUG_MONITOR
|
||||
OutputDebugStringW(_T("Process failed\n"));
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Process failed\n");
|
||||
}
|
||||
} else {
|
||||
ret = (long)(pCurProcInfo->uid);
|
||||
|
||||
|
@ -428,9 +421,9 @@ extern "C"
|
|||
memcpy(piCopy, &pi, sizeof(PROCESS_INFORMATION));
|
||||
_beginthread(waitProcTermination, 0, (void *)piCopy);
|
||||
|
||||
#ifdef DEBUG_MONITOR
|
||||
OutputDebugStringW(_T("Process started\n"));
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Process started\n");
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&cs);
|
||||
}
|
||||
|
@ -605,9 +598,6 @@ extern "C"
|
|||
|
||||
HANDLE hProc;
|
||||
pProcInfo_t pCurProcInfo = findProcInfo(uid);
|
||||
#ifdef DEBUG_MONITOR
|
||||
wchar_t buffer[100];
|
||||
#endif
|
||||
|
||||
if (NULL == pCurProcInfo) {
|
||||
if (SIG_INT == signal) { // Try another way
|
||||
|
@ -616,11 +606,9 @@ extern "C"
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("Spawner received signal %i for process %i\n"), signal,
|
||||
pCurProcInfo->pid);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Spawner received signal %i for process %i\n", signal, pCurProcInfo->pid);
|
||||
}
|
||||
|
||||
hProc = OpenProcess(SYNCHRONIZE, 0, pCurProcInfo->pid);
|
||||
|
||||
|
@ -638,28 +626,24 @@ extern "C"
|
|||
ret = 0;
|
||||
break;
|
||||
case SIG_TERM:
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("Spawner received TERM signal for process %i\n"),
|
||||
pCurProcInfo->pid);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Spawner received TERM signal for process %i\n", pCurProcInfo->pid);
|
||||
}
|
||||
SetEvent(pCurProcInfo->eventTerminate);
|
||||
#ifdef DEBUG_MONITOR
|
||||
OutputDebugStringW(_T("Spawner signaled TERM event\n"));
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Spawner signaled TERM event\n");
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case SIG_KILL:
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("Spawner received KILL signal for process %i\n"),
|
||||
pCurProcInfo->pid);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Spawner received KILL signal for process %i\n", pCurProcInfo->pid);
|
||||
}
|
||||
SetEvent(pCurProcInfo->eventKill);
|
||||
#ifdef DEBUG_MONITOR
|
||||
OutputDebugStringW(_T("Spawner signaled KILL event\n"));
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Spawner signaled KILL event\n");
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
case SIG_INT:
|
||||
|
@ -830,9 +814,6 @@ void cleanUpProcBlock(pProcInfo_t pCurProcInfo) {
|
|||
void _cdecl waitProcTermination(void *pv) {
|
||||
PROCESS_INFORMATION *pi = (PROCESS_INFORMATION *)pv;
|
||||
int i;
|
||||
#ifdef DEBUG_MONITOR
|
||||
wchar_t buffer[1000];
|
||||
#endif
|
||||
|
||||
// wait for process termination
|
||||
WaitForSingleObject(pi->hProcess, INFINITE);
|
||||
|
@ -840,11 +821,9 @@ void _cdecl waitProcTermination(void *pv) {
|
|||
for (i = 0; i < MAX_PROCS; ++i) {
|
||||
if (pInfo[i].pid == pi->dwProcessId) {
|
||||
cleanUpProcBlock(pInfo + i);
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("waitProcTermination: set PID %i to 0\n"),
|
||||
pi->dwProcessId);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"waitProcTermination: set PID %i to 0\n", pi->dwProcessId);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(pi->hProcess);
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
#include <jni.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "org_eclipse_cdt_utils_spawner_Spawner.h"
|
||||
#include "util.h"
|
||||
|
||||
//#define READ_REPORT
|
||||
#include "org_eclipse_cdt_utils_spawner_Spawner.h"
|
||||
|
||||
void ThrowByName(JNIEnv *env, const char *name, const char *msg);
|
||||
|
||||
|
@ -61,9 +61,6 @@ extern "C"
|
|||
jbyte tmpBuf[BUFF_SIZE];
|
||||
int nBuffOffset = 0;
|
||||
HANDLE handle = channelToHandle(env, channel);
|
||||
#ifdef DEBUG_MONITOR
|
||||
_TCHAR buffer[1000];
|
||||
#endif
|
||||
OVERLAPPED overlapped;
|
||||
overlapped.Offset = 0;
|
||||
overlapped.OffsetHigh = 0;
|
||||
|
@ -83,12 +80,9 @@ extern "C"
|
|||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MONITOR
|
||||
#ifdef READ_REPORT
|
||||
_stprintf(buffer, _T("Start read %i\n"), fd);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR) && isTraceEnabled(CDT_TRACE_READ_REPORT)) {
|
||||
cdtTrace(L"Start read %p\n", handle);
|
||||
}
|
||||
|
||||
while (len > nBuffOffset) {
|
||||
DWORD nNumberOfBytesToRead = min(len - nBuffOffset, BUFF_SIZE);
|
||||
|
@ -110,10 +104,9 @@ extern "C"
|
|||
}
|
||||
if (err != 0) {
|
||||
char *lpMsgBuf;
|
||||
#ifdef DEBUG_MONITOR
|
||||
_stprintf(buffer, _T("Read failed - %i, error %i\n"), fd, err);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Read failed - %p, error %i\n", handle, err);
|
||||
}
|
||||
if (err !=
|
||||
ERROR_MORE_DATA) { // Otherwise error means just that there are more data than buffer can accept
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
|
@ -128,10 +121,9 @@ extern "C"
|
|||
} else {
|
||||
// buffer overflow?
|
||||
// according to msdn this happens in message read mode only
|
||||
#ifdef DEBUG_MONITOR
|
||||
_stprintf(buffer, _T("Buffer full - %i, bytes read: %i\n"), fd, nNumberOfBytesRead);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Buffer full - %p, bytes read: %i\n", handle, nNumberOfBytesRead);
|
||||
}
|
||||
// nNumberOfBytesRead can be 0 here for unknown reason (bug 269223)
|
||||
nNumberOfBytesRead = nNumberOfBytesToRead;
|
||||
}
|
||||
|
@ -155,12 +147,9 @@ extern "C"
|
|||
}
|
||||
}
|
||||
CloseHandle(overlapped.hEvent);
|
||||
#ifdef DEBUG_MONITOR
|
||||
#ifdef READ_REPORT
|
||||
_stprintf(buffer, _T("End read %i - bytes read: %d\n"), fd, nBuffOffset);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR) && isTraceEnabled(CDT_TRACE_READ_REPORT)) {
|
||||
cdtTrace(L"End read %p - bytes read: %d\n", handle, nBuffOffset);
|
||||
}
|
||||
return nBuffOffset; // This is a real full readed length
|
||||
}
|
||||
|
||||
|
@ -171,16 +160,13 @@ extern "C"
|
|||
Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_close0(JNIEnv *env, jobject proc, jobject channel) {
|
||||
int rc;
|
||||
HANDLE handle = channelToHandle(env, channel);
|
||||
#ifdef DEBUG_MONITOR
|
||||
_TCHAR buffer[1000];
|
||||
_stprintf(buffer, _T("Close %i\n"), fd);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Close %p\n", handle);
|
||||
}
|
||||
rc = (CloseHandle(handle) ? 0 : -1);
|
||||
#ifdef DEBUG_MONITOR
|
||||
_stprintf(buffer, _T("Closed %i\n"), fd);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Closed %p\n", handle);
|
||||
}
|
||||
return (rc ? GetLastError() : 0);
|
||||
}
|
||||
|
||||
|
@ -235,16 +221,13 @@ extern "C"
|
|||
Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_close0(JNIEnv *env, jobject proc, jobject channel) {
|
||||
int rc;
|
||||
HANDLE handle = channelToHandle(env, channel);
|
||||
#ifdef DEBUG_MONITOR
|
||||
_TCHAR buffer[1000];
|
||||
_stprintf(buffer, _T("Close %i\n"), fd);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Close %p\n", handle);
|
||||
}
|
||||
FlushFileBuffers(handle);
|
||||
rc = (CloseHandle(handle) ? 0 : -1);
|
||||
#ifdef DEBUG_MONITOR
|
||||
_stprintf(buffer, _T("Closed %i\n"), fd);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Closed %p\n", handle);
|
||||
}
|
||||
return (rc ? GetLastError() : 0);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include <jni.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#include "org_eclipse_cdt_utils_spawner_Spawner.h"
|
||||
|
||||
extern void JNICALL ThrowByName(JNIEnv *env, const char *name, const char *msg);
|
||||
|
@ -92,16 +94,12 @@ int interruptProcess(int pid) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MONITOR
|
||||
_TCHAR buffer[1000];
|
||||
#endif
|
||||
int rc = 0;
|
||||
consoleHWND = NULL;
|
||||
|
||||
#ifdef DEBUG_MONITOR
|
||||
_stprintf(buffer, _T("Try to interrupt process %i\n"), pid);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Try to interrupt process %i\n", pid);
|
||||
}
|
||||
// Find console
|
||||
EnumWindows(find_child_console, (LPARAM)pid);
|
||||
|
||||
|
@ -157,16 +155,12 @@ int interruptProcess(int pid) {
|
|||
if (child_thread) {
|
||||
AttachThreadInput(GetCurrentThreadId(), child_thread, FALSE);
|
||||
}
|
||||
#ifdef DEBUG_MONITOR
|
||||
_stprintf(buffer, _T("Sent Ctrl-C & Ctrl-Break to process %i\n"), pid);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Sent Ctrl-C & Ctrl-Break to process %i\n", pid);
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_MONITOR
|
||||
} else {
|
||||
_stprintf(buffer, _T("Cannot find console for process %i\n"), pid);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
} else if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Cannot find console for process %i\n", pid);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
#include <psapi.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
//#define DEBUG_MONITOR
|
||||
#include "util.h"
|
||||
|
||||
#define MAX_CMD_LINE_LENGTH (2049)
|
||||
#define PIPE_NAME_LENGTH 100
|
||||
|
||||
|
@ -157,22 +158,22 @@ int main() {
|
|||
int len = wcslen(argv[i]);
|
||||
int requiredSize = nPos + len + 2;
|
||||
if (requiredSize > 32 * 1024) {
|
||||
#ifdef DEBUG_MONITOR
|
||||
OutputDebugStringW(_T("Command line too long!\n"));
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Command line too long!\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
ensureSize(&szCmdLine, &nCmdLineLength, requiredSize);
|
||||
if (NULL == szCmdLine) {
|
||||
#ifdef DEBUG_MONITOR
|
||||
OutputDebugStringW(_T("Not enough memory to build cmd line!\n"));
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Not enough memory to build cmd line!\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (0 > (nCpyLen = copyTo(szCmdLine + nPos, argv[i], len, nCmdLineLength - nPos))) {
|
||||
#ifdef DEBUG_MONITOR
|
||||
OutputDebugStringW(_T("Not enough space to build command line\n"));
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Not enough space to build command line\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
nPos += nCpyLen;
|
||||
|
@ -184,10 +185,6 @@ int main() {
|
|||
STARTUPINFOW si = {sizeof(si)};
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
DWORD dwExitCode = 0;
|
||||
#ifdef DEBUG_MONITOR
|
||||
int currentPID = GetCurrentProcessId();
|
||||
wchar_t buffer[MAX_CMD_LINE_LENGTH];
|
||||
#endif
|
||||
|
||||
BOOL exitProc = FALSE;
|
||||
HANDLE waitEvent = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[4]);
|
||||
|
@ -212,10 +209,9 @@ int main() {
|
|||
nCounter);
|
||||
swprintf(errPipeName, sizeof(errPipeName) / sizeof(errPipeName[0]), L"\\\\.\\pipe\\stderr%08i%010i", parentPid,
|
||||
nCounter);
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, _T("Pipes: %s, %s, %s\n"), inPipeName, outPipeName, errPipeName);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Pipes: %s, %s, %s\n", inPipeName, outPipeName, errPipeName);
|
||||
}
|
||||
|
||||
HANDLE stdHandles[3];
|
||||
|
||||
|
@ -230,11 +226,11 @@ int main() {
|
|||
(stdHandles[1] = CreateFileW(outPipeName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, &sa))) ||
|
||||
(INVALID_HANDLE_VALUE ==
|
||||
(stdHandles[2] = CreateFileW(errPipeName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, &sa)))) {
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("Failed to open pipe %i, %i, %i: %i\n"), stdHandles[0],
|
||||
stdHandles[1], stdHandles[2], GetLastError());
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Failed to open pipe %i, %i, %i: %i\n", stdHandles[0], stdHandles[1], stdHandles[2],
|
||||
GetLastError());
|
||||
}
|
||||
CloseHandle(stdHandles[0]);
|
||||
CloseHandle(stdHandles[1]);
|
||||
CloseHandle(stdHandles[2]);
|
||||
|
@ -246,40 +242,37 @@ int main() {
|
|||
|
||||
if (!SetStdHandle(STD_INPUT_HANDLE, stdHandles[0]) || !SetStdHandle(STD_OUTPUT_HANDLE, stdHandles[1]) ||
|
||||
!SetStdHandle(STD_ERROR_HANDLE, stdHandles[2])) {
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("Failed to reassign standard streams: %i\n"),
|
||||
GetLastError());
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Failed to reassign standard streams: %i\n", GetLastError());
|
||||
}
|
||||
CloseHandle(stdHandles[0]);
|
||||
CloseHandle(stdHandles[1]);
|
||||
CloseHandle(stdHandles[2]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MONITOR_DETAILS
|
||||
wchar_t *lpvEnv = GetEnvironmentStringsW();
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR_DETAILS)) {
|
||||
wchar_t *lpvEnv = GetEnvironmentStringsW();
|
||||
|
||||
// If the returned pointer is NULL, exit.
|
||||
if (lpvEnv == NULL) {
|
||||
OutputDebugStringW(_T("Cannot Read Environment\n"));
|
||||
} else {
|
||||
// Variable strings are separated by NULL byte, and the block is
|
||||
// terminated by a NULL byte.
|
||||
// If the returned pointer is NULL, exit.
|
||||
if (lpvEnv == NULL) {
|
||||
cdtTrace(L"Cannot Read Environment\n");
|
||||
} else {
|
||||
// Variable strings are separated by NULL byte, and the block is
|
||||
// terminated by a NULL byte.
|
||||
|
||||
OutputDebugStringW(_T("Starter: Environment\n"));
|
||||
for (wchar_t *lpszVariable = (wchar_t *)lpvEnv; *lpszVariable; lpszVariable += wcslen(lpszVariable) + 1) {
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("%s\n"), lpszVariable);
|
||||
OutputDebugStringW(buffer);
|
||||
cdtTrace(L"Starter: Environment\n");
|
||||
for (wchar_t *lpszVariable = lpvEnv; *lpszVariable; lpszVariable += wcslen(lpszVariable) + 1) {
|
||||
cdtTrace(L"%s\n", lpszVariable);
|
||||
}
|
||||
|
||||
FreeEnvironmentStringsW(lpvEnv);
|
||||
}
|
||||
|
||||
FreeEnvironmentStringsW(lpvEnv);
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("Starting: %s\n"), szCmdLine);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Starting: %s\n", szCmdLine);
|
||||
}
|
||||
// Create job object
|
||||
HANDLE hJob = CreateJobObject(NULL, NULL);
|
||||
if (hJob != NULL) {
|
||||
|
@ -290,16 +283,14 @@ 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))) {
|
||||
#ifdef DEBUG_MONITOR
|
||||
OutputDebugStringW(_T("Cannot set job information\n"));
|
||||
DisplayErrorMessage();
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Cannot set job information\n");
|
||||
DisplayErrorMessage();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifdef DEBUG_MONITOR
|
||||
OutputDebugStringW(_T("Cannot create job object\n"));
|
||||
} else if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Cannot create job object\n");
|
||||
DisplayErrorMessage();
|
||||
#endif
|
||||
}
|
||||
// Spawn the other processes as part of this Process Group
|
||||
// If this process is already part of a job, the flag CREATE_BREAKAWAY_FROM_JOB
|
||||
|
@ -317,22 +308,19 @@ int main() {
|
|||
CloseHandle(stdHandles[2]);
|
||||
|
||||
if (f) {
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("Process %i started\n"), pi.dwProcessId);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Process %i started\n", pi.dwProcessId);
|
||||
}
|
||||
SetEvent(waitEvent); // Means that process has been spawned
|
||||
CloseHandle(pi.hThread);
|
||||
h[1] = pi.hProcess;
|
||||
|
||||
if (NULL != hJob) {
|
||||
if (!AssignProcessToJobObject(hJob, pi.hProcess)) {
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("Cannot assign process %i to a job\n"),
|
||||
pi.dwProcessId);
|
||||
OutputDebugStringW(buffer);
|
||||
DisplayErrorMessage();
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Cannot assign process %i to a job\n", pi.dwProcessId);
|
||||
DisplayErrorMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,11 +331,9 @@ int main() {
|
|||
switch (event) {
|
||||
case WAIT_OBJECT_0 + 0: // SIGINT
|
||||
case WAIT_OBJECT_0 + 4: // CTRL-C
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("starter (PID %i) received CTRL-C event\n"),
|
||||
currentPID);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"starter (PID %i) received CTRL-C event\n", GetCurrentProcessId());
|
||||
}
|
||||
if ((event == (WAIT_OBJECT_0 + 0)) && isCygwin(h[1])) {
|
||||
// Need to issue a kill command
|
||||
wchar_t kill[1024];
|
||||
|
@ -365,11 +351,9 @@ int main() {
|
|||
|
||||
case WAIT_OBJECT_0 + 1: // App terminated normally
|
||||
// Make it's exit code our exit code
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]),
|
||||
_T("starter: launched process has been terminated(PID %i)\n"), pi.dwProcessId);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"starter: launched process has been terminated(PID %i)\n", pi.dwProcessId);
|
||||
}
|
||||
GetExitCodeProcess(pi.hProcess, &dwExitCode);
|
||||
exitProc = TRUE;
|
||||
break;
|
||||
|
@ -382,11 +366,9 @@ int main() {
|
|||
case WAIT_OBJECT_0 + 3: // KILL
|
||||
{
|
||||
const wchar_t *signal = (event == WAIT_OBJECT_0 + 2) ? L"TERM" : L"KILL";
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("starter received %s event (PID %i)\n"), signal,
|
||||
currentPID);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"starter received %s event (PID %i)\n", signal, GetCurrentProcessId());
|
||||
}
|
||||
if (isCygwin(h[1])) {
|
||||
// Need to issue a kill command
|
||||
wchar_t kill[1024];
|
||||
|
@ -403,10 +385,10 @@ int main() {
|
|||
|
||||
if (NULL != hJob) {
|
||||
if (!TerminateJobObject(hJob, (DWORD)-1)) {
|
||||
#ifdef DEBUG_MONITOR
|
||||
OutputDebugStringW(_T("Cannot terminate job\n"));
|
||||
DisplayErrorMessage();
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Cannot terminate job\n");
|
||||
DisplayErrorMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,20 +398,17 @@ int main() {
|
|||
|
||||
default:
|
||||
// Unexpected code
|
||||
#ifdef DEBUG_MONITOR
|
||||
DisplayErrorMessage();
|
||||
#endif
|
||||
if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
DisplayErrorMessage();
|
||||
}
|
||||
exitProc = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifdef DEBUG_MONITOR
|
||||
swprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), _T("Cannot start: %s\n"), szCmdLine);
|
||||
OutputDebugStringW(buffer);
|
||||
} else if (isTraceEnabled(CDT_TRACE_MONITOR)) {
|
||||
cdtTrace(L"Cannot start: %s\n", szCmdLine);
|
||||
|
||||
DisplayErrorMessage();
|
||||
#endif
|
||||
}
|
||||
|
||||
free(szCmdLine);
|
||||
|
|
75
core/org.eclipse.cdt.core.native/native_src/win/util.c
Normal file
75
core/org.eclipse.cdt.core.native/native_src/win/util.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2020 Torbjörn Svensson and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Torbjörn Svensson - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#include <stdio.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;
|
||||
}
|
||||
|
||||
switch (traceKind) {
|
||||
case CDT_TRACE_MONITOR:
|
||||
return monitor;
|
||||
case CDT_TRACE_MONITOR_DETAILS:
|
||||
return monitorDetails;
|
||||
case CDT_TRACE_READ_REPORT:
|
||||
return readReport;
|
||||
default:
|
||||
cdtTrace(L"Invalid trace kind supplied: %d\n", traceKind);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void cdtTrace(const wchar_t *fmt, ...) {
|
||||
va_list ap;
|
||||
wchar_t *buffer = NULL;
|
||||
int size = 0;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
do {
|
||||
// Free previous buffer
|
||||
free(buffer);
|
||||
|
||||
// Allocate a slightly larger buffer
|
||||
size += 256;
|
||||
buffer = (wchar_t *)malloc(size * sizeof(wchar_t));
|
||||
|
||||
if (!buffer) {
|
||||
// malloc failed
|
||||
OutputDebugStringW(L"Failed to allocate buffer to format message into.\n");
|
||||
va_end(ap);
|
||||
return;
|
||||
}
|
||||
} while (-1 == vswprintf(buffer, size, fmt, ap) && errno == ERANGE);
|
||||
va_end(ap);
|
||||
|
||||
// Send the output
|
||||
OutputDebugStringW(buffer);
|
||||
|
||||
// Clean up
|
||||
free(buffer);
|
||||
}
|
26
core/org.eclipse.cdt.core.native/native_src/win/util.h
Normal file
26
core/org.eclipse.cdt.core.native/native_src/win/util.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2020 Torbjörn Svensson and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Torbjörn Svensson - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <windows.h>
|
||||
|
||||
typedef enum { CDT_TRACE_MONITOR, CDT_TRACE_MONITOR_DETAILS, CDT_TRACE_READ_REPORT } TraceKind_t;
|
||||
|
||||
bool isTraceEnabled(const TraceKind_t traceKind);
|
||||
void cdtTrace(const wchar_t *fmt, ...);
|
||||
|
||||
#endif /* UTIL_H */
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Add table
Reference in a new issue