Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Cortell2009-07-07 15:57:21 -0400
committerJohn Cortell2009-07-07 15:57:21 -0400
commitcb443c104d4c8252b2d6a1c670d06bb1406c256e (patch)
tree988a43a25ee2aa543830335ca0dae6369c27a290 /core/org.eclipse.cdt.core.win32/library
parent3cdfd7abfa1f3f803768a7e8c6620b9699e811f9 (diff)
downloadorg.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
Diffstat (limited to 'core/org.eclipse.cdt.core.win32/library')
-rw-r--r--core/org.eclipse.cdt.core.win32/library/Win32ProcessEx.c46
-rw-r--r--core/org.eclipse.cdt.core.win32/library/starter/starter.cpp45
2 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 a069bd5f01..31ae73c146 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 8cdcbcc840..67473ec1c5 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);
}

Back to the top