diff options
author | John Cortell | 2009-07-07 19:57:21 +0000 |
---|---|---|
committer | John Cortell | 2009-07-07 19:57:21 +0000 |
commit | cb443c104d4c8252b2d6a1c670d06bb1406c256e (patch) | |
tree | 988a43a25ee2aa543830335ca0dae6369c27a290 | |
parent | 3cdfd7abfa1f3f803768a7e8c6620b9699e811f9 (diff) | |
download | org.eclipse.cdt-cb443c104d4c8252b2d6a1c670d06bb1406c256e.tar.gz org.eclipse.cdt-cb443c104d4c8252b2d6a1c670d06bb1406c256e.tar.xz org.eclipse.cdt-cb443c104d4c8252b2d6a1c670d06bb1406c256e.zip |
Fixed:
282735 - starter.exe can end up rapid-firing CTRL-C's to process that won't die
282736 - starter.exe should support SIGKILL
-rw-r--r-- | core/org.eclipse.cdt.core.win32/library/Win32ProcessEx.c | 46 | ||||
-rw-r--r-- | core/org.eclipse.cdt.core.win32/library/starter/starter.cpp | 45 | ||||
-rw-r--r-- | core/org.eclipse.cdt.core.win32/os/win32/x86/spawner.dll | bin | 39844 -> 784638 bytes | |||
-rw-r--r-- | core/org.eclipse.cdt.core.win32/os/win32/x86/starter.exe | bin | 30051 -> 583286 bytes |
4 files changed, 62 insertions, 29 deletions
diff --git a/core/org.eclipse.cdt.core.win32/library/Win32ProcessEx.c b/core/org.eclipse.cdt.core.win32/library/Win32ProcessEx.c index a069bd5f019..31ae73c146c 100644 --- a/core/org.eclipse.cdt.core.win32/library/Win32ProcessEx.c +++ b/core/org.eclipse.cdt.core.win32/library/Win32ProcessEx.c @@ -39,10 +39,11 @@ typedef struct _procInfo { int uid; // quasi-unique process ID; we have to create it to avoid duplicated pid // (actually this impossible from OS point of view but it is still possible // a clash of new created and already finished process with one and the same PID. - // 3 events connected to this process (see starter) - HANDLE eventBreak; + // 4 events connected to this process (see starter) + HANDLE eventBreak; // signaled when Spawner.interrupt() is called; mildest of the terminate requests (SIGINT signal in UNIX world) HANDLE eventWait; - HANDLE eventTerminate; + HANDLE eventTerminate; // signaled when Spawner.terminate() is called; more forceful terminate request (SIGTERM signal in UNIX world) + HANDLE eventKill; // signaled when Spawner.kill() is called; most forceful terminate request (SIGKILL signal in UNIX world) } procInfo_t, * pProcInfo_t; static int procCounter = 0; // Number of running processes @@ -146,6 +147,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0 wchar_t eventBreakName[20]; wchar_t eventWaitName[20]; wchar_t eventTerminateName[20]; + wchar_t eventKillName[20]; #ifdef DEBUG_MONITOR wchar_t buffer[1000]; #endif @@ -217,14 +219,14 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0 swprintf(eventBreakName, L"SABreak%p", pCurProcInfo); swprintf(eventWaitName, L"SAWait%p", pCurProcInfo); swprintf(eventTerminateName, L"SATerm%p", pCurProcInfo); - pCurProcInfo -> eventBreak = CreateEventW(NULL, TRUE, FALSE, eventBreakName); - ResetEvent(pCurProcInfo -> eventBreak); - pCurProcInfo -> eventWait = CreateEventW(NULL, TRUE, FALSE, eventWaitName); - ResetEvent(pCurProcInfo -> eventWait); - pCurProcInfo -> eventTerminate = CreateEventW(NULL, TRUE, FALSE, eventTerminateName); - ResetEvent(pCurProcInfo -> eventTerminate); - - swprintf(szCmdLine, L"\"%sstarter.exe\" %i %i %s %s %s ", path, pid, nLocalCounter, eventBreakName, eventWaitName, eventTerminateName); + swprintf(eventKillName, L"SAKill%p", pCurProcInfo); + + pCurProcInfo->eventBreak = CreateEventW(NULL, TRUE, FALSE, eventBreakName); + pCurProcInfo->eventWait = CreateEventW(NULL, TRUE, FALSE, eventWaitName); + pCurProcInfo->eventTerminate = CreateEventW(NULL, FALSE, FALSE, eventTerminateName); + pCurProcInfo->eventKill = CreateEventW(NULL, FALSE, FALSE, eventKillName); + + swprintf(szCmdLine, L"\"%sstarter.exe\" %i %i %s %s %s %s ", path, pid, nLocalCounter, eventBreakName, eventWaitName, eventTerminateName, eventKillName); nPos = wcslen(szCmdLine); // Prepare command line @@ -667,15 +669,27 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise // Temporary do nothing ret = 0; break; - case SIG_KILL: case SIG_TERM: #ifdef DEBUG_MONITOR - swprintf(buffer, _T("Spawner received KILL or TERM signal for process %i\n"), + swprintf(buffer, _T("Spawner received TERM signal for process %i\n"), pCurProcInfo -> pid); OutputDebugStringW(buffer); #endif SetEvent(pCurProcInfo -> eventTerminate); #ifdef DEBUG_MONITOR + OutputDebugStringW(_T("Spawner signalled TERM event\n")); +#endif + ret = 0; + break; + + case SIG_KILL: +#ifdef DEBUG_MONITOR + swprintf(buffer, _T("Spawner received KILL signal for process %i\n"), + pCurProcInfo -> pid); + OutputDebugStringW(buffer); +#endif + SetEvent(pCurProcInfo -> eventKill); +#ifdef DEBUG_MONITOR OutputDebugStringW(_T("Spawner signalled KILL event\n")); #endif ret = 0; @@ -841,6 +855,12 @@ void cleanUpProcBlock(pProcInfo_t pCurProcInfo) pCurProcInfo -> eventTerminate = 0; } + if(0 != pCurProcInfo -> eventKill) + { + CloseHandle(pCurProcInfo -> eventKill); + pCurProcInfo -> eventKill = 0; + } + pCurProcInfo -> pid = 0; } diff --git a/core/org.eclipse.cdt.core.win32/library/starter/starter.cpp b/core/org.eclipse.cdt.core.win32/library/starter/starter.cpp index 8cdcbcc840d..67473ec1c57 100644 --- a/core/org.eclipse.cdt.core.win32/library/starter/starter.cpp +++ b/core/org.eclipse.cdt.core.win32/library/starter/starter.cpp @@ -139,8 +139,8 @@ int main() { wchar_t ** argv = CommandLineToArgvW(GetCommandLine(), &argc); // Make sure that we've been passed the right number of arguments - if (argc < 7) { - _tprintf(_T("Usage: %s (Three InheritableEventHandles) (CommandLineToSpawn)\n"), + if (argc < 8) { + _tprintf(_T("Usage: %s (four inheritable event handles) (CommandLineToSpawn)\n"), argv[0]); return(0); } @@ -151,7 +151,7 @@ int main() { szCmdLine[0]= 0; int nPos = 0; - for(int i = 6; i < argc; ++i) + for(int i = 7; i < argc; ++i) { int nCpyLen; int len= wcslen(argv[i]); @@ -192,9 +192,11 @@ int main() { BOOL exitProc = FALSE; HANDLE waitEvent = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[4]); - HANDLE h[3]; - h[0] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[3]); - h[2] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[5]); // This is a terminate event + HANDLE h[4]; + h[0] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[3]); // simulated SIGINT +// h[1] we reserve for the process handle + h[2] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[5]); // simulated SIGTERM + h[3] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[6]); // simulated SIGKILL SetConsoleCtrlHandler(HandlerRoutine, TRUE); int parentPid = wcstol(argv[1], NULL, 10); @@ -306,9 +308,10 @@ int main() { { // Wait for the spawned-process to die or for the event // indicating that the processes should be forcibly killed. - switch (WaitForMultipleObjects(3, h, FALSE, INFINITE)) + DWORD event = WaitForMultipleObjects(4, h, FALSE, INFINITE); + switch (event) { - case WAIT_OBJECT_0 + 0: // Send Ctrl-C + case WAIT_OBJECT_0 + 0: // SIGINT #ifdef DEBUG_MONITOR swprintf(buffer, _T("starter (PID %i) received CTRL-C event\n"), currentPID); OutputDebugStringW(buffer); @@ -338,16 +341,23 @@ int main() { GetExitCodeProcess(pi.hProcess, &dwExitCode); exitProc = TRUE; break; - - case WAIT_OBJECT_0 + 2: // Kill + + // Terminate and Kill behavior differ only for cygwin processes, where + // we use the cygwin 'kill' command. We send a SIGKILL in one case, + // SIGTERM in the other. For non-cygwin processes, both requests + // are treated exactly the same + case WAIT_OBJECT_0 + 2: // TERM + case WAIT_OBJECT_0 + 3: // KILL + { + const wchar_t* signal = (event == WAIT_OBJECT_0 + 2) ? L"TERM" : L"KILL"; #ifdef DEBUG_MONITOR - swprintf(buffer, _T("starter received KILL event (PID %i)\n"), currentPID); + swprintf(buffer, _T("starter received %s event (PID %i)\n"), signal, currentPID); OutputDebugStringW(buffer); #endif if (isCygwin(h[1])) { // Need to issue a kill command wchar_t kill[1024]; - swprintf(kill, L"kill -SIGTERM %d", pi.dwProcessId); + swprintf(kill, L"kill -SIG%s %d", signal, pi.dwProcessId); if (!runCygwinCommand(kill)) { // fall back to console event GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); @@ -365,10 +375,13 @@ int main() { DisplayErrorMessage(); #endif } - } else - exitProc = TRUE; + } + + // Note that we keep trucking until the child process terminates (case WAIT_OBJECT_0 + 1) break; - default: + } + + default: // Unexpected code #ifdef DEBUG_MONITOR DisplayErrorMessage(); @@ -378,7 +391,6 @@ int main() { } } - CloseHandle(pi.hProcess); } else { #ifdef DEBUG_MONITOR swprintf(buffer, _T("Cannot start: %s\n"), szCmdLine); @@ -397,6 +409,7 @@ int main() { CloseHandle(h[0]); CloseHandle(h[1]); CloseHandle(h[2]); + CloseHandle(h[3]); return(dwExitCode); } diff --git a/core/org.eclipse.cdt.core.win32/os/win32/x86/spawner.dll b/core/org.eclipse.cdt.core.win32/os/win32/x86/spawner.dll Binary files differindex 04d429dcf7e..c4f44ce32e2 100644 --- a/core/org.eclipse.cdt.core.win32/os/win32/x86/spawner.dll +++ b/core/org.eclipse.cdt.core.win32/os/win32/x86/spawner.dll diff --git a/core/org.eclipse.cdt.core.win32/os/win32/x86/starter.exe b/core/org.eclipse.cdt.core.win32/os/win32/x86/starter.exe Binary files differindex be5741c82bd..df89ff715f3 100644 --- a/core/org.eclipse.cdt.core.win32/os/win32/x86/starter.exe +++ b/core/org.eclipse.cdt.core.win32/os/win32/x86/starter.exe |