1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 574131: SIGTERM should let app do a gracefully exit on win

Let the process have some time to do a graceful exit with the signal
SIGTERM. If the process is still alive after 1s, raise the SIGKILL
signal and hammer down the process.
The 1s is aligned on all platforms and handled in JAVA.

Contributed by STMicroelectronics

Change-Id: Iff2f7727c1ac37b190c60a01774f106638eeeeaa
Signed-off-by: Torbjörn Svensson <torbjorn.svensson@st.com>
This commit is contained in:
Torbjörn Svensson 2021-10-15 20:25:53 +02:00
parent 46d7fb74da
commit cd73469b01
4 changed files with 46 additions and 42 deletions

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.cdt.core.native;singleton:=true
Bundle-Version: 6.1.300.qualifier
Bundle-Version: 6.1.400.qualifier
Bundle-Activator: org.eclipse.cdt.internal.core.natives.CNativePlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin

View file

@ -246,6 +246,20 @@ bool createCommandLine(int argc, wchar_t **argv, wchar_t **cmdLine) {
return true;
}
void raiseSignal(HANDLE h, int pid, const wchar_t *signal) {
if (isCygwin(h)) {
// Need to issue a kill command
wchar_t kill[1024];
swprintf(kill, sizeof(kill) / sizeof(kill[0]), L"kill -%s %d", signal, pid);
if (!runCygwinCommand(kill)) {
// fall back to console event
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
}
} else {
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
}
}
int main() {
int argc;
@ -384,24 +398,23 @@ int main() {
}
}
#define SIGINT_EVENT (WAIT_OBJECT_0 + 0)
#define EXIT_EVENT (WAIT_OBJECT_0 + 1)
#define SIGTERM_EVENT (WAIT_OBJECT_0 + 2)
#define SIGKILL_EVENT (WAIT_OBJECT_0 + 3)
#define CTRLC_EVENT (WAIT_OBJECT_0 + 4)
while (!exitProc) {
// Wait for the spawned-process to die or for the event
// indicating that the processes should be forcibly killed.
DWORD event = WaitForMultipleObjects(5, h, FALSE, INFINITE);
switch (event) {
case WAIT_OBJECT_0 + 0: // SIGINT
case WAIT_OBJECT_0 + 4: // CTRL-C
case SIGINT_EVENT:
case CTRLC_EVENT:
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])) {
// Need to issue a kill command
wchar_t kill[1024];
swprintf(kill, sizeof(kill) / sizeof(kill[0]), L"kill -SIGINT %d", pi.dwProcessId);
if (!runCygwinCommand(kill)) {
// fall back to console event
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
}
if (event == SIGINT_EVENT) {
raiseSignal(h[1], pi.dwProcessId, L"SIGINT");
} else {
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
}
@ -409,8 +422,8 @@ int main() {
SetEvent(waitEvent);
break;
case WAIT_OBJECT_0 + 1: // App terminated normally
// Make it's exit code our exit code
case EXIT_EVENT: // App terminated normally
// Make it's exit code our exit code
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
cdtTrace(L"starter: launched process has been terminated(PID %i)\n", pi.dwProcessId);
}
@ -418,43 +431,34 @@ int main() {
exitProc = TRUE;
break;
// 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";
case SIGTERM_EVENT:
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
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];
swprintf(kill, sizeof(kill) / sizeof(kill[0]), L"kill -%s %d", signal, pi.dwProcessId);
if (!runCygwinCommand(kill)) {
// fall back to console event
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
}
} else {
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
cdtTrace(L"starter received TERM event (PID %i)\n", GetCurrentProcessId());
}
raiseSignal(h[1], pi.dwProcessId, L"TERM");
SetEvent(waitEvent);
if (hJob) {
if (!TerminateJobObject(hJob, (DWORD)-1)) {
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
cdtTrace(L"Cannot terminate job\n");
DisplayErrorMessage();
}
// Note that we keep trucking until the child process terminates (case EXIT_EVENT)
break;
case SIGKILL_EVENT:
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
cdtTrace(L"starter received KILL event (PID %i)\n", GetCurrentProcessId());
}
raiseSignal(h[1], pi.dwProcessId, L"KILL");
SetEvent(waitEvent);
if (hJob && !TerminateJobObject(hJob, (DWORD)-1)) {
if (isTraceEnabled(CDT_TRACE_SPAWNER)) {
cdtTrace(L"Cannot terminate job\n");
DisplayErrorMessage();
}
}
// Note that we keep trucking until the child process terminates (case WAIT_OBJECT_0 + 1)
// Note that we keep trucking until the child process terminates (case EXIT_EVENT)
break;
}
default:
// Unexpected code

View file

@ -23,7 +23,7 @@
<relativePath>../../pom.xml</relativePath>
</parent>
<version>6.1.300-SNAPSHOT</version>
<version>6.1.400-SNAPSHOT</version>
<artifactId>org.eclipse.cdt.core.native</artifactId>
<packaging>eclipse-plugin</packaging>