diff --git a/core/org.eclipse.cdt.core.linux.aarch64/os/linux/aarch64/libspawner.so b/core/org.eclipse.cdt.core.linux.aarch64/os/linux/aarch64/libspawner.so index ca8ff04d3a4..a9921d7f546 100755 Binary files a/core/org.eclipse.cdt.core.linux.aarch64/os/linux/aarch64/libspawner.so and b/core/org.eclipse.cdt.core.linux.aarch64/os/linux/aarch64/libspawner.so differ diff --git a/core/org.eclipse.cdt.core.linux.ppc64le/os/linux/ppc64le/libspawner.so b/core/org.eclipse.cdt.core.linux.ppc64le/os/linux/ppc64le/libspawner.so index 41b7f6df88a..c4b0c33d21c 100755 Binary files a/core/org.eclipse.cdt.core.linux.ppc64le/os/linux/ppc64le/libspawner.so and b/core/org.eclipse.cdt.core.linux.ppc64le/os/linux/ppc64le/libspawner.so differ diff --git a/core/org.eclipse.cdt.core.linux.x86_64/os/linux/x86_64/libspawner.so b/core/org.eclipse.cdt.core.linux.x86_64/os/linux/x86_64/libspawner.so index 3c3e2ff384e..3f888bd9a18 100755 Binary files a/core/org.eclipse.cdt.core.linux.x86_64/os/linux/x86_64/libspawner.so and b/core/org.eclipse.cdt.core.linux.x86_64/os/linux/x86_64/libspawner.so differ diff --git a/core/org.eclipse.cdt.core.macosx/os/macosx/x86/libspawner.jnilib b/core/org.eclipse.cdt.core.macosx/os/macosx/x86/libspawner.jnilib index b12ec7c661e..ba694c0f98c 100755 Binary files a/core/org.eclipse.cdt.core.macosx/os/macosx/x86/libspawner.jnilib and b/core/org.eclipse.cdt.core.macosx/os/macosx/x86/libspawner.jnilib differ diff --git a/core/org.eclipse.cdt.core.macosx/os/macosx/x86_64/libspawner.jnilib b/core/org.eclipse.cdt.core.macosx/os/macosx/x86_64/libspawner.jnilib index 56f3928f5d1..77938703087 100755 Binary files a/core/org.eclipse.cdt.core.macosx/os/macosx/x86_64/libspawner.jnilib and b/core/org.eclipse.cdt.core.macosx/os/macosx/x86_64/libspawner.jnilib differ diff --git a/core/org.eclipse.cdt.core.native/native_src/Makefile b/core/org.eclipse.cdt.core.native/native_src/Makefile index 8aa198fa7e7..dcd644faced 100644 --- a/core/org.eclipse.cdt.core.native/native_src/Makefile +++ b/core/org.eclipse.cdt.core.native/native_src/Makefile @@ -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" \ diff --git a/core/org.eclipse.cdt.core.native/native_src/unix/spawner.c b/core/org.eclipse.cdt.core.native/native_src/unix/spawner.c index 503130dd4ea..c02c8d26130 100644 --- a/core/org.eclipse.cdt.core.native/native_src/unix/spawner.c +++ b/core/org.eclipse.cdt.core.native/native_src/unix/spawner.c @@ -19,33 +19,51 @@ #include #include #include +#include #include "exec0.h" #include -#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; diff --git a/core/org.eclipse.cdt.core.native/native_src/win/Win32ProcessEx.c b/core/org.eclipse.cdt.core.native/native_src/win/Win32ProcessEx.c index 6be590a3999..1ddf55ce21b 100644 --- a/core/org.eclipse.cdt.core.native/native_src/win/Win32ProcessEx.c +++ b/core/org.eclipse.cdt.core.native/native_src/win/Win32ProcessEx.c @@ -24,6 +24,8 @@ #include #include +#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); diff --git a/core/org.eclipse.cdt.core.native/native_src/win/iostream.c b/core/org.eclipse.cdt.core.native/native_src/win/iostream.c index df1d0b875c0..c63d2cfd482 100644 --- a/core/org.eclipse.cdt.core.native/native_src/win/iostream.c +++ b/core/org.eclipse.cdt.core.native/native_src/win/iostream.c @@ -21,9 +21,9 @@ #include #include -#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); } diff --git a/core/org.eclipse.cdt.core.native/native_src/win/raise.c b/core/org.eclipse.cdt.core.native/native_src/win/raise.c index 27fd6e90488..7efd2c6d331 100644 --- a/core/org.eclipse.cdt.core.native/native_src/win/raise.c +++ b/core/org.eclipse.cdt.core.native/native_src/win/raise.c @@ -18,6 +18,8 @@ #include #include +#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; diff --git a/core/org.eclipse.cdt.core.native/native_src/win/starter.c b/core/org.eclipse.cdt.core.native/native_src/win/starter.c index 5fc193dea08..d6b7384a463 100644 --- a/core/org.eclipse.cdt.core.native/native_src/win/starter.c +++ b/core/org.eclipse.cdt.core.native/native_src/win/starter.c @@ -26,7 +26,8 @@ #include #include -//#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); diff --git a/core/org.eclipse.cdt.core.native/native_src/win/util.c b/core/org.eclipse.cdt.core.native/native_src/win/util.c new file mode 100644 index 00000000000..3191751c972 --- /dev/null +++ b/core/org.eclipse.cdt.core.native/native_src/win/util.c @@ -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 + +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); +} diff --git a/core/org.eclipse.cdt.core.native/native_src/win/util.h b/core/org.eclipse.cdt.core.native/native_src/win/util.h new file mode 100644 index 00000000000..d5991da771b --- /dev/null +++ b/core/org.eclipse.cdt.core.native/native_src/win/util.h @@ -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 +#include + +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 */ diff --git a/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/pty.dll b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/pty.dll index 63c49e6b3d9..b74a2eba759 100755 Binary files a/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/pty.dll and b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/pty.dll differ diff --git a/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/spawner.dll b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/spawner.dll index 014b6769072..4ba9c3c75f8 100755 Binary files a/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/spawner.dll and b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/spawner.dll differ diff --git a/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/starter.exe b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/starter.exe index f7b6d02d50b..700d95a4062 100755 Binary files a/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/starter.exe and b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/starter.exe differ