Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 7 additions & 12 deletions src/coreclr/debug/ee/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5903,8 +5903,7 @@ void Debugger::SendDataBreakpoint(Thread *thread, CONTEXT *context,
LOG((LF_CORDB, LL_INFO10000, "D::SDB: breakpoint BP:0x%x\n", breakpoint));

_ASSERTE((g_pEEInterface->GetThread() &&
!g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled) ||
g_fInControlC);
!g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled));

_ASSERTE(ThreadHoldsLock());

Expand Down Expand Up @@ -5951,8 +5950,7 @@ void Debugger::SendBreakpoint(Thread *thread, CONTEXT *context,
LOG((LF_CORDB, LL_INFO10000, "D::SB: breakpoint BP:0x%x\n", breakpoint));

_ASSERTE((g_pEEInterface->GetThread() &&
!g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled) ||
g_fInControlC);
!g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled));

_ASSERTE(ThreadHoldsLock());

Expand Down Expand Up @@ -6095,8 +6093,7 @@ void Debugger::SendStep(Thread *thread, CONTEXT *context,
stepper, reason));

_ASSERTE((g_pEEInterface->GetThread() &&
!g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled) ||
g_fInControlC);
!g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled));

_ASSERTE(ThreadHoldsLock());

Expand Down Expand Up @@ -6423,8 +6420,7 @@ void Debugger::SyncAllThreads(DebuggerLockHolder *dbgLockHolder)
Thread *pThread = g_pEEInterface->GetThread();
(void)pThread; //prevent "unused variable" error from GCC
_ASSERTE((pThread &&
!pThread->m_fPreemptiveGCDisabled) ||
g_fInControlC);
!pThread->m_fPreemptiveGCDisabled));

_ASSERTE(ThreadHoldsLock());

Expand Down Expand Up @@ -9007,8 +9003,7 @@ void Debugger::ThreadStarted(Thread* pRuntimeThread)
//

_ASSERTE((g_pEEInterface->GetThread() &&
!g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled) ||
g_fInControlC);
!g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled));
_ASSERTE(ThreadHoldsLock());

DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
Expand Down Expand Up @@ -9145,7 +9140,7 @@ BOOL Debugger::SuspendComplete(bool isEESuspendedForGC)
// We can't throw here (we're in the middle of the runtime suspension logic).
// But things below us throw. So we catch the exception, but then what state are we in?

if (!isEESuspendedForGC) {_ASSERTE((!g_pEEInterface->GetThread() || !g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled) || g_fInControlC); }
if (!isEESuspendedForGC) {_ASSERTE((!g_pEEInterface->GetThread() || !g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled)); }
if (!isEESuspendedForGC) { _ASSERTE(ThisIsHelperThreadWorker()); }

STRESS_LOG0(LF_CORDB, LL_INFO10000, "D::SC: suspension complete\n");
Expand Down Expand Up @@ -9982,7 +9977,7 @@ void Debugger::FuncEvalComplete(Thread* pThread, DebuggerEval *pDE)


_ASSERTE(pDE->m_completed);
_ASSERTE((g_pEEInterface->GetThread() && !g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled) || g_fInControlC);
_ASSERTE((g_pEEInterface->GetThread() && !g_pEEInterface->GetThread()->m_fPreemptiveGCDisabled));
_ASSERTE(ThreadHoldsLock());

//
Expand Down
7 changes: 0 additions & 7 deletions src/coreclr/pal/inc/pal.h
Original file line number Diff line number Diff line change
Expand Up @@ -4093,7 +4093,6 @@ struct PAL_SEHException

typedef BOOL (*PHARDWARE_EXCEPTION_HANDLER)(PAL_SEHException* ex);
typedef BOOL (*PHARDWARE_EXCEPTION_SAFETY_CHECK_FUNCTION)(PCONTEXT contextRecord, PEXCEPTION_RECORD exceptionRecord);
typedef VOID (*PTERMINATION_REQUEST_HANDLER)(int terminationExitCode);
typedef DWORD (*PGET_GCMARKER_EXCEPTION_CODE)(LPVOID ip);

PALIMPORT
Expand All @@ -4116,12 +4115,6 @@ PAL_ThrowExceptionFromContext(
IN CONTEXT* context,
IN PAL_SEHException* ex);

PALIMPORT
VOID
PALAPI
PAL_SetTerminationRequestHandler(
IN PTERMINATION_REQUEST_HANDLER terminationRequestHandler);

PALIMPORT
VOID
PALAPI
Expand Down
10 changes: 2 additions & 8 deletions src/coreclr/pal/src/exception/signal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,15 +846,9 @@ static void sigterm_handler(int code, siginfo_t *siginfo, void *context)
{
PROCCreateCrashDumpIfEnabled(code, siginfo, false);
}
// g_pSynchronizationManager shouldn't be null if PAL is initialized.
_ASSERTE(g_pSynchronizationManager != nullptr);

g_pSynchronizationManager->SendTerminationRequestToWorkerThread();
}
else
{
restore_signal_and_resend(SIGTERM, &g_previous_sigterm);
}

restore_signal_and_resend(SIGTERM, &g_previous_sigterm);
}

#ifdef INJECT_ACTIVATION_SIGNAL
Expand Down
4 changes: 0 additions & 4 deletions src/coreclr/pal/src/include/pal/corunix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -976,10 +976,6 @@ namespace CorUnix
CPalThread *pThread
) = 0;

virtual
PAL_ERROR
SendTerminationRequestToWorkerThread() = 0;

//
// This routine is primarily meant for use by WaitForMultipleObjects[Ex].
// The caller must individually release each of the returned controller
Expand Down
80 changes: 3 additions & 77 deletions src/coreclr/pal/src/synchmgr/synchmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,6 @@ SET_DEFAULT_DEBUG_CHANNEL(SYNC); // some headers have code with asserts, so do t

const int CorUnix::CThreadSynchronizationInfo::PendingSignalingsArraySize;

// We use the synchronization manager's worker thread to handle
// process termination requests. It does so by calling the
// registered handler function.
PTERMINATION_REQUEST_HANDLER g_terminationRequestHandler = NULL;

// Set the handler for process termination requests.
VOID PALAPI PAL_SetTerminationRequestHandler(
IN PTERMINATION_REQUEST_HANDLER terminationHandler)
{
g_terminationRequestHandler = terminationHandler;
}

namespace CorUnix
{
/////////////////////////////////
Expand Down Expand Up @@ -1160,25 +1148,6 @@ namespace CorUnix
return palErr;
}

/*++
Method:
CPalSynchronizationManager::SendTerminationRequestToWorkerThread

Send a request to the worker thread to initiate process termination.
--*/
PAL_ERROR CPalSynchronizationManager::SendTerminationRequestToWorkerThread()
{
PAL_ERROR palErr = GetInstance()->WakeUpLocalWorkerThread(SynchWorkerCmdTerminationRequest);
if (palErr != NO_ERROR)
{
ERROR("Failed to wake up worker thread [errno=%d {%s%}]\n",
errno, strerror(errno));
palErr = ERROR_INTERNAL_ERROR;
}

return palErr;
}

/*++
Method:
CPalSynchronizationManager::AreAPCsPending
Expand Down Expand Up @@ -1558,22 +1527,6 @@ namespace CorUnix
return palErr;
}

// Entry point routine for the thread that initiates process termination.
DWORD PALAPI TerminationRequestHandlingRoutine(LPVOID pArg)
{
// Call the termination request handler if one is registered.
if (g_terminationRequestHandler != NULL)
{
// The process will terminate normally by calling exit.
// We use an exit code of '128 + signo'. This is a convention used in popular
// shells to calculate an exit code when the process was terminated by a signal.
// This is also used by the Process.ExitCode implementation.
g_terminationRequestHandler(128 + SIGTERM);
}

return 0;
}

/*++
Method:
CPalSynchronizationManager::WorkerThread
Expand Down Expand Up @@ -1612,31 +1565,6 @@ namespace CorUnix
}
switch (swcCmd)
{
case SynchWorkerCmdTerminationRequest:
// This worker thread is being asked to initiate process termination

HANDLE hTerminationRequestHandlingThread;
palErr = InternalCreateThread(pthrWorker,
NULL,
0,
&TerminationRequestHandlingRoutine,
NULL,
0,
PalWorkerThread,
NULL,
&hTerminationRequestHandlingThread);

if (NO_ERROR != palErr)
{
ERROR("Unable to create worker thread\n");
}

if (hTerminationRequestHandlingThread != NULL)
{
CloseHandle(hTerminationRequestHandlingThread);
}

break;
case SynchWorkerCmdNop:
TRACE("Synch Worker: received SynchWorkerCmdNop\n");
if (fShuttingDown)
Expand Down Expand Up @@ -1776,8 +1704,7 @@ namespace CorUnix
}

_ASSERT_MSG(SynchWorkerCmdNop == swcWorkerCmd ||
SynchWorkerCmdShutdown == swcWorkerCmd ||
SynchWorkerCmdTerminationRequest == swcWorkerCmd,
SynchWorkerCmdShutdown == swcWorkerCmd,
"Unknown worker command code %u\n", swcWorkerCmd);

TRACE("Got cmd %u from process pipe\n", swcWorkerCmd);
Expand Down Expand Up @@ -2216,9 +2143,8 @@ namespace CorUnix
"Value too big for swcWorkerCmd\n");

_ASSERT_MSG((SynchWorkerCmdNop == swcWorkerCmd) ||
(SynchWorkerCmdShutdown == swcWorkerCmd) ||
(SynchWorkerCmdTerminationRequest == swcWorkerCmd),
"WakeUpLocalWorkerThread supports only SynchWorkerCmdNop, SynchWorkerCmdShutdown, and SynchWorkerCmdTerminationRequest."
(SynchWorkerCmdShutdown == swcWorkerCmd),
"WakeUpLocalWorkerThread supports only SynchWorkerCmdNop and SynchWorkerCmdShutdown."
"[received cmd=%d]\n", swcWorkerCmd);

BYTE byCmd = (BYTE)(swcWorkerCmd & 0xFF);
Expand Down
3 changes: 0 additions & 3 deletions src/coreclr/pal/src/synchmgr/synchmanager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,6 @@ namespace CorUnix
{
SynchWorkerCmdNop,
SynchWorkerCmdShutdown,
SynchWorkerCmdTerminationRequest,
SynchWorkerCmdLast
};

Expand Down Expand Up @@ -783,8 +782,6 @@ namespace CorUnix
PAPCFUNC pfnAPC,
ULONG_PTR uptrData);

virtual PAL_ERROR SendTerminationRequestToWorkerThread();

virtual bool AreAPCsPending(CPalThread * pthrTarget);

virtual PAL_ERROR DispatchPendingAPCs(CPalThread * pthrCurrent);
Expand Down
7 changes: 0 additions & 7 deletions src/coreclr/vm/ceemain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,13 +372,6 @@ static BOOL WINAPI DbgCtrlCHandler(DWORD dwCtrlType)
else
#endif // DEBUGGING_SUPPORTED
{
if (dwCtrlType == CTRL_CLOSE_EVENT || dwCtrlType == CTRL_SHUTDOWN_EVENT)
{
// Initiate shutdown so the ProcessExit handlers run
ForceEEShutdown(SCA_ReturnWhenShutdownComplete);
}

g_fInControlC = true; // only for weakening assertions in checked build.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no reason to weaken assertions after Ctrl+C has been pressed. The runtime should still function fine until all signal handlers finish.

return FALSE; // keep looking for a real handler.
}
}
Expand Down
21 changes: 0 additions & 21 deletions src/coreclr/vm/exceptionhandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,24 +162,6 @@ static inline void UpdatePerformanceMetrics(CrawlFrame *pcfThisFrame, BOOL bIsRe
ETW::ExceptionLog::ExceptionThrown(pcfThisFrame, bIsRethrownException, bIsNewException);
}

#ifdef TARGET_UNIX
static LONG volatile g_termination_triggered = 0;

void HandleTerminationRequest(int terminationExitCode)
{
// We set a non-zero exit code to indicate the process didn't terminate cleanly.
// This value can be changed by the user by setting Environment.ExitCode in the
// ProcessExit event. We only start termination on the first SIGTERM signal
// to ensure we don't overwrite an exit code already set in ProcessExit.
if (InterlockedCompareExchange(&g_termination_triggered, 1, 0) == 0)
{
SetLatchedExitCode(terminationExitCode);

ForceEEShutdown(SCA_ExitProcessWhenShutdownComplete);
}
}
#endif

void InitializeExceptionHandling()
{
EH_LOG((LL_INFO100, "InitializeExceptionHandling(): ExInfo size: 0x%x bytes\n", sizeof(ExInfo)));
Expand All @@ -192,9 +174,6 @@ void InitializeExceptionHandling()

// Register handler for determining whether the specified IP has code that is a GC marker for GCCover
PAL_SetGetGcMarkerExceptionCode(GetGcMarkerExceptionCode);

// Register handler for termination requests (e.g. SIGTERM)
PAL_SetTerminationRequestHandler(HandleTerminationRequest);
#endif // TARGET_UNIX
}

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/listlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ class ListLockBase
{
WRAPPER_NO_CONTRACT;
// There should not be any of these around
_ASSERTE(m_pHead == NULL || dbg_fDrasticShutdown || g_fInControlC);
_ASSERTE(m_pHead == NULL);

if (m_fInited)
{
Expand Down
6 changes: 0 additions & 6 deletions src/coreclr/vm/vars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,6 @@ bool g_fManagedAttach = false;
//
bool g_fWeControlLifetime = false;

#ifdef _DEBUG
// The following should only be used for assertions. (Famous last words).
bool dbg_fDrasticShutdown = false;
#endif
bool g_fInControlC = false;

#endif // #ifndef DACCESS_COMPILE

#ifdef DACCESS_COMPILE
Expand Down
6 changes: 0 additions & 6 deletions src/coreclr/vm/vars.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,12 +500,6 @@ EXTERN const char g_psBaseLibrarySatelliteAssemblyName[];
//
EXTERN bool g_fWeControlLifetime;

#ifdef _DEBUG
// The following should only be used for assertions. (Famous last words).
EXTERN bool dbg_fDrasticShutdown;
#endif
EXTERN bool g_fInControlC;

// There is a global table of prime numbers that's available for e.g. hashing
extern const DWORD g_rgPrimes[71];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,16 @@ public class ExitCodeTests
[DllImport("libc", SetLastError = true)]
private static extern int kill(int pid, int sig);

[ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[InlineData(null)]
[InlineData(0)]
[InlineData(42)]
[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[PlatformSpecific(TestPlatforms.AnyUnix)] // SIGTERM signal.
public void SigTermExitCode(int? exitCodeOnSigterm)
public void SigTermExitCode()
{
Action<string> action = (string sigTermExitCode) =>
Action action = () =>
{
if (!string.IsNullOrEmpty(sigTermExitCode))
AppDomain.CurrentDomain.ProcessExit += (sender, args) =>
{
AppDomain.CurrentDomain.ProcessExit += (sender, args) =>
{
Assert.Same(AppDomain.CurrentDomain, sender);
Environment.ExitCode = int.Parse(sigTermExitCode);
};
}
Assert.Fail("AppDomain.ProcessExit is not expected to be called when the process is killed by SIGTERM");
};

Console.WriteLine("Application started");

Expand All @@ -42,7 +35,7 @@ public void SigTermExitCode(int? exitCodeOnSigterm)
RemoteInvokeOptions options = new RemoteInvokeOptions();
options.StartInfo.RedirectStandardOutput = true;
options.CheckExitCode = false;
using (RemoteInvokeHandle remoteExecution = RemoteExecutor.Invoke(action, exitCodeOnSigterm?.ToString() ?? string.Empty, options))
using (RemoteInvokeHandle remoteExecution = RemoteExecutor.Invoke(action, options))
{
Process process = remoteExecution.Process;

Expand All @@ -58,8 +51,8 @@ public void SigTermExitCode(int? exitCodeOnSigterm)
bool exited = process.WaitForExit(RemoteExecutor.FailWaitTimeoutMilliseconds);
Assert.True(exited);

// Check exit code
Assert.Equal(exitCodeOnSigterm ?? 128 + SIGTERM, process.ExitCode);
// Check that the exit code is 143 (128 + SIGTERM).
Assert.Equal(143, process.ExitCode);
}
}
}
Expand Down
Loading
Loading