[+] Linux Exception Handlers and AuExit::ETriggerLevel::eSigQuitNow

[*] Linux stability fixes
[+] AuProcAddresses.UNIX.[cpp/hpp]
This commit is contained in:
Reece Wilson 2024-03-05 11:06:29 +00:00
parent 8b29e73f96
commit 2371794d47
23 changed files with 640 additions and 87 deletions

View File

@ -14,12 +14,15 @@ namespace Aurora::Exit
// Runtime deinitialize
eSafeTermination,
// A fatal exception was caught by the watchdog. The process is on its way out
// A fatal exception was caught by the watchdog. The process is on its way out and there's nothing you can do about it.
eFatalException,
// Control+C was sent, termination must follow
// Control+C was sent, termination should follow. Filter with CancelExit.
eSigTerminate,
// Do not attempt to block this signal. Terminal UX or system power events are asserting it's time to go.
eSigQuitNow,
// Something went wrong in the process. These could be frequent depending on the process
eProblematicEvent
));

View File

@ -246,8 +246,8 @@ namespace Aurora
{
bool bFIODisableBatching { false };
bool bIOLinuxHasProcIpcPerms { false };
AuUInt8 uSignalTerminate { 27 };
AuUInt8 uSignalGAIOWorkerThreadDone { 28 };
AuUInt8 uSignalTerminate { 64 - 3 };
AuUInt8 uSignalGAIOWorkerThreadDone { 64 - 4 };
};
struct ProcessConfig

View File

@ -118,3 +118,25 @@ ANNOYING_TAGONLY(void *operator new[], PROTOTYPE_LATTER(std::size_t s, std::alig
#include <AuroraAlloc.cpp>
#endif
*/
#if defined(AURORA_PLATFORM_LINUX)
namespace std
{
struct type_info;
}
extern void AU_NORETURN __au_cxa_throw(void *pException, std::type_info*, void (*fDtor)(void *pThis));
extern "C" inline void AU_NORETURN __cxa_throw(void *pException, std::type_info *typeInfo, void (*fDtor)(void *pThis))
{
__au_cxa_throw(pException, typeInfo, fDtor);
}
extern "C" AuUInt32 _au_Unwind_RaiseException(struct _Unwind_Exception *pUnwind);
extern "C" AuUInt32 _Unwind_RaiseException(struct _Unwind_Exception *pUnwind)
{
return _au_Unwind_RaiseException(pUnwind);
}
#endif

View File

@ -9,6 +9,7 @@
#include <sys/syscall.h>
#include <linux/futex.h>
#include <Time/Time.hpp>
#include <dlfcn.h>
#define AURORA_IS_GLIBC
@ -25,6 +26,23 @@ namespace Aurora
void InitLinuxAddresses()
{
pgetsockname = getsockname;
#if defined(RTLD_NEXT)
p__cxa_throw = (decltype(p__cxa_throw))dlsym(RTLD_NEXT, "__cxa_throw");
p_Unwind_RaiseException = (decltype(p_Unwind_RaiseException))dlsym(RTLD_NEXT, "_Unwind_RaiseException");
#endif
#if defined(RTLD_DEFAULT)
if (!p_Unwind_RaiseException)
{
p_Unwind_RaiseException = (decltype(p_Unwind_RaiseException))dlsym(RTLD_DEFAULT, "_Unwind_RaiseException");
}
if (!p__cxa_throw)
{
p__cxa_throw = (decltype(p__cxa_throw))dlsym(RTLD_DEFAULT, "__cxa_throw");
}
#endif
}
template <typename... T>

View File

@ -65,4 +65,7 @@ namespace Aurora
inline int (*pgetsockname)(int sockfd, struct sockaddr *addr,
socklen_t *addrlen);
inline void (AU_NORETURN *p__cxa_throw)(void *pException, std::type_info *typeInfo, void (*fDtor)(void *pThis));
inline AuUInt32 (*p_Unwind_RaiseException)(void *pException);
}

29
Source/AuProcAddresses.UNIX.cpp Executable file
View File

@ -0,0 +1,29 @@
/***
Copyright (C) 2024 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: AuProcAddresses.UNIX.cpp
Date: 2024-3-5
Author: Reece
***/
#include "RuntimeInternal.hpp"
#include "AuProcAddresses.UNIX.hpp"
#include <Source/Debug/ExceptionWatcher.Unix.hpp>
namespace Aurora::Process
{
void PosixForkResetLocks();
}
namespace Aurora
{
void PosixDoForkHooks()
{
Process::PosixForkResetLocks();
Debug::DeinitSignalHandlers();
}
void PosixTerminate()
{
killpg(0, SIGKILL);
}
}

14
Source/AuProcAddresses.UNIX.hpp Executable file
View File

@ -0,0 +1,14 @@
/***
Copyright (C) 2024 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: AuProcAddresses.UNIX.hpp
Date: 2024-3-5
Author: Reece
***/
#pragma once
namespace Aurora
{
void PosixDoForkHooks();
void PosixTerminate();
}

View File

@ -9,10 +9,16 @@
#if defined(AURORA_IS_MODERNNT_DERIVED)
#include "AuProcAddresses.NT.hpp"
#elif defined(AURORA_IS_LINUX_DERIVED)
#endif
#if defined(AURORA_IS_LINUX_DERIVED)
#include "AuProcAddresses.Linux.hpp"
#endif
#if defined(AURORA_IS_POSIX_DERIVED)
#include "AuProcAddresses.UNIX.hpp"
#endif
namespace Aurora
{
void InitProcAddresses();

View File

@ -19,6 +19,10 @@
#include "Stack.Unix.hpp"
#endif
#if defined(AURORA_IS_POSIX_DERIVED)
#include "ExceptionWatcher.Unix.hpp"
#endif
#include "ErrorStack.hpp"
namespace Aurora::Debug
@ -379,7 +383,7 @@ namespace Aurora::Debug
try
{
backTraceBuffer.reserve(512 - 32); // 512 seems like a nice length minus some overhead for a bucket allocator
backTraceBuffer.reserve(512 - 32); // 512 seems like a nice length minus some overhead for an allocators header
backTraceBuffer += fmt::format("\tAddress: 0x{:x} (0x{:x})", frame.relAddress ? frame.relAddress : frame.address, frame.relAddress ? frame.address : frame.relAddress);
@ -401,10 +405,36 @@ namespace Aurora::Debug
}
if (frame.label)
{
auto parts = AuSplitString(frame.label.value(), "+");
if (auto resultName = DemangleName(parts[0]))
{
if (resultName.value() == parts[0])
{
backTraceBuffer += fmt::format(" ({}) \n", frame.label.value());
}
else
{
backTraceBuffer += fmt::format(" ({} a/k/a {}) \n", resultName.value(), frame.label.value());
}
}
else if (auto resultName = DemangleName(frame.label.value()))
{
if (resultName.value() == frame.label.value())
{
backTraceBuffer += fmt::format(" ({}) \n", frame.label.value());
}
else
{
backTraceBuffer += fmt::format(" ({} a/k/a {}) \n", resultName.value(), frame.label.value());
}
}
else
{
backTraceBuffer += fmt::format(" ({}) \n", frame.label.value());
}
}
else
{
backTraceBuffer += ", unknown function\n";
}
@ -464,5 +494,9 @@ namespace Aurora::Debug
#if defined(AURORA_IS_MODERNNT_DERIVED)
InitNT();
#endif
#if defined(AURORA_IS_POSIX_DERIVED)
InitUNIX();
#endif
}
}

View File

@ -50,6 +50,8 @@ namespace Aurora::Debug
AUKN_SYM const AuString &ThreadMessage::ToString()
{
static const AuString kUnknownError = "Unknown Error.";
if (this->pStringMessage)
{
return *this->pStringMessage;
@ -83,7 +85,7 @@ namespace Aurora::Debug
return tlsLastMessageError = fmt::format("OS = {}", (AuUInt)*optOsErrorCode);
}
return "Unknown error.";
return kUnknownError;
}
static thread_local ErrorStack *tlsErrorStackBase;

View File

@ -1,5 +1,5 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
Copyright (C) 2021-2024 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ExceptionWatcher.Linux.cpp
Date: 2021-6-12
@ -8,15 +8,427 @@
#include <Source/RuntimeInternal.hpp>
#include "ExceptionWatcher.Unix.hpp"
#include "Debug.hpp"
#include <Source/Telemetry/Telemetry.hpp>
#include <Source/Grug/AuGrug.hpp>
#include <Source/Console/Console.hpp>
#include <Source/Exit/AuExit.hpp>
#include "ErrorStack.hpp"
#if defined(AURORA_PLATFORM_LINUX)
#include "unwind.h"
#endif
#include "Stack.Unix.hpp"
#include <cxxabi.h>
#if defined(AURORA_PLATFORM_LINUX) && defined(AURORA_ARCH_X64)
#define DEBUG_ABI_ALPHA
#endif
#if defined(AURORA_PLATFORM_LINUX) && (defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86))
#define DEBUG_ABI_IS_IT_AND_SYSV_LIKE
#endif
namespace Aurora::Debug
{
void PlatformHandleFatal(bool fatal, bool bNoExit)
static const AuUInt8 kCriticalAlwaysCoreDumpSignals[] {
SIGABRT,
SIGBUS,
SIGILL,
SIGIOT,
SIGQUIT,
SIGSEGV,
SIGSYS,
SIGTRAP,
//SIGUNUSED,
SIGFPE,
SIGXFSZ
};
static const AuUInt8 kTypeIgnoreNOP = 0;
static const AuUInt8 kTypeIgnoreAndLog = 1;
static const AuUInt8 kTypeCoreDump = 2;
static AuUInt8 gSignalHandlerMap[64] {};
static void SaveMinidump(void *optContext,
void *pException,
int iSignal,
AuUInt32 uThread,
AuString &pathOut)
{
}
static void PlatformHandleFatalEx(bool fatal, bool bNoExit, void *context, AuUInt32 uThreadID)
{
AuString path;
SaveMinidump(context, nullptr, 0, uThreadID, path);
if (fatal)
{
if (path.size())
{
Telemetry::NewBlackBoxEntryMinidump report {};
report.includesRx = false;
report.resource.path = path;
report.resource.type = Telemetry::ENewBlackBoxResourceType::eLocal;
Telemetry::ReportDyingBreath(report);
}
PosixTerminate();
}
}
struct SigArrow : Grug::Arrow
{
int signal {};
void *context {};
AuUInt32 uPosixThread {};
AuUInt thread;
};
static void SendLogMessage(Grug::Arrow *pArrow)
{
auto pArrowEx = AuStaticCast<SigArrow>(pArrow);
AuLogDbg("Caught signal {} ({}) on {}/{}", strsignal(pArrowEx->signal), pArrowEx->signal, pArrowEx->thread, pArrowEx->uPosixThread);
Exit::PostLevel((AuThreads::IAuroraThread *)pArrowEx->thread, Exit::ETriggerLevel::eProblematicEvent);
}
static void SendCoreDump(Grug::Arrow *pArrow)
{
auto pArrowEx = AuStaticCast<SigArrow>(pArrow);
{
StackTrace trace;
if (pArrowEx->context)
{
trace = DumpContext(pArrowEx->context);
}
if (gRuntimeConfig.debug.bPrintExceptionStackTracesOut)
{
AuLogWarn("Fatal Signal: 0x{:x}, {} ({})", pArrowEx->thread, strsignal(pArrowEx->signal), pArrowEx->signal);
AuLogWarn("{}", StringifyStackTrace(trace));
}
{
Telemetry::NewBlockboxEntry entry;
entry.type = Telemetry::ENewBlackBoxEntry::eStackWarning;
entry.stack.fenceId = ReportStackTrace(trace, AuToString(pArrowEx->signal));
entry.stack.backtrace = trace;
Telemetry::Report(entry);
}
}
{
Exit::PostLevel((AuThreads::IAuroraThread *)pArrowEx->thread, Exit::ETriggerLevel::eFatalException);
}
{
AuString path;
SaveMinidump(pArrowEx->context, nullptr, pArrowEx->signal, pArrowEx->uPosixThread, path);
if (path.size())
{
Telemetry::NewBlackBoxEntryMinidump report {};
report.includesRx = false;
report.resource.path = path;
report.resource.type = Telemetry::ENewBlackBoxResourceType::eLocal;
Telemetry::ReportDyingBreath(report);
}
}
{
Grug::GrugFlushWrites();
Grug::GrugFlushFlushs();
Console::Pump();
}
PosixTerminate();
}
static void PosixCrashTrap(int signal, siginfo_t *si, void *context)
{
void (*pSendExitSignal_f)(Grug::Arrow *);
SigArrow arrow;
arrow.signal = signal;
arrow.thread = AuThreads::GetThreadId();
arrow.context = context;
arrow.uPosixThread = getpid();
switch (gSignalHandlerMap[signal])
{
case kTypeIgnoreNOP:
return;
case kTypeIgnoreAndLog:
pSendExitSignal_f = SendLogMessage;
break;
case kTypeCoreDump:
pSendExitSignal_f = SendCoreDump;
break;
}
Grug::HurlArrow(&arrow, pSendExitSignal_f, {});
Grug::ArrowWait(&arrow);
if (pSendExitSignal_f == SendCoreDump)
{
PosixTerminate();
}
}
void PlatformHandleFatal(bool bFatal, bool bNoExit)
{
PlatformHandleFatalEx(bFatal, bNoExit, nullptr, getpid());
}
static void InstallSignalHandlerOnSignal(AuUInt8 uSignal)
{
struct sigaction action =
{
.sa_handler = (void (*)(int))PosixCrashTrap,
.sa_flags = SA_ONSTACK
};
sigemptyset(&action.sa_mask);
sigaction(uSignal, &action, nullptr);
}
static void RemoveSignalHandlerOnSignal(AuUInt8 uSignal)
{
struct sigaction action =
{
.sa_handler = SIG_DFL,
.sa_flags = SA_ONSTACK
};
sigemptyset(&action.sa_mask);
sigaction(uSignal, &action, nullptr);
}
static void OverrideCriticalSignals()
{
for (AU_ITERATE_N(i, AuArraySize(kCriticalAlwaysCoreDumpSignals)))
{
auto uSignal = kCriticalAlwaysCoreDumpSignals[i];
gSignalHandlerMap[uSignal] = kTypeCoreDump;
InstallSignalHandlerOnSignal(uSignal);
}
}
void InitUNIX()
{
OverrideCriticalSignals();
}
void DeinitSignalHandlers()
{
for (AU_ITERATE_N(uSignal, AuArraySize(gSignalHandlerMap)))
{
if (gSignalHandlerMap[uSignal] == kTypeIgnoreNOP)
{
continue;
}
RemoveSignalHandlerOnSignal(uSignal);
}
}
static void ReportException(void *pException,
std::type_info *pInfo,
const StackTrace &trace,
AuConsumer<const AuString &> func = {})
{
AuString message { "EMPTY" };
if (pInfo)
{
//AuLogDbg("Base RTTI of the type info: {}", ((char ****)pInfo)[0][-1][1]);
bool bIsStdExceptionDerived {};
#if defined(DEBUG_ABI_IS_IT_AND_SYSV_LIKE)
if (strcmp(((char ****)pInfo)[0][-1][1], "N10__cxxabiv120__si_class_type_infoE") == 0)
{
char **pInfoCur = ((char ****)pException)[0][-1];
while (pInfoCur)
{
if (strcmp(pInfoCur[1], "St9exception") == 0)
{
bIsStdExceptionDerived = true;
break;
}
auto pOld = pInfoCur;
pInfoCur = (char **)pInfoCur[2];
if (pOld == pInfoCur)
{
break;
}
}
}
#endif
if (*pInfo == typeid(const char*))
{
message = fmt::format("Exception Type: {}, Message: {}", pInfo->name(), pException ? *(const char**)pException : "<NULL>");
}
else if (*pInfo == typeid(char* const))
{
message = fmt::format("Exception Type: {}, Message: {}", pInfo->name(), pException ? *(const char**)pException : "<NULL>");
}
#define ADD_FMT_PRIM(type) \
else if (*pInfo == typeid(type)) \
{ \
message = fmt::format("Exception Type: {}, Data: {}", pInfo->name(), pException ? *(type*)pException : type {}); \
}
ADD_FMT_PRIM(std::string)
ADD_FMT_PRIM(double)
ADD_FMT_PRIM(float)
ADD_FMT_PRIM(AuUInt8)
ADD_FMT_PRIM(AuUInt16)
ADD_FMT_PRIM(AuUInt32)
ADD_FMT_PRIM(AuUInt64)
ADD_FMT_PRIM(AuInt8)
ADD_FMT_PRIM(AuInt16)
ADD_FMT_PRIM(AuInt32)
ADD_FMT_PRIM(AuInt64)
else if (bIsStdExceptionDerived)
{
message = fmt::format("Exception Type: {}, Message: {}", pInfo->name(), ((std::exception *)pException)->what());
}
else
{
message = fmt::format("Exception Type: {}", pInfo->name());
}
}
if (func)
{
func(message);
}
{
Telemetry::NewBlockboxEntry entry;
entry.type = Telemetry::ENewBlackBoxEntry::eStackWarning;
entry.stack.fenceId = ReportStackTrace(trace, message);
entry.stack.backtrace = trace;
Telemetry::Report(entry);
auto pStr = AuMakeSharedPanic<AuString>(message);
// auto pTrace = AuMakeSharedThrow<StackTrace>(trace);
if (ShouldPushErrorStackInternal())
{
auto pMessage = AuMakeSharedThrow<ThreadMessage>();
pMessage->optStackTrace = trace;
pMessage->pStringMessage = pStr;
PushErrorStackInternal(pMessage);
}
}
}
static AU_NORETURN void __au_cxa_throw(void *pException, std::type_info *pInfo, void (*fDtor)(void *pThis))
{
if (Grug::IsGrug())
{
SysAssert(p__cxa_throw, "NST");
p__cxa_throw(pException, pInfo, fDtor);
}
{
AU_DEBUG_MEMCRUNCH;
auto trace = GetStackTrace();
if (gRuntimeConfig.debug.bPrintExceptionStackTracesOut)
{
ReportException(pException, pInfo, trace, [&](const AuString &str)
{
AuLogWarn("Local Clang Exception: 0x{:x}, {}", AuUInt(pException), str.c_str());
AuLogWarn("{}", StringifyStackTrace(trace));
});
}
else
{
ReportException(pException, pInfo, trace);
}
AuExit::PostLevel(AuThreads::GetThread(), Aurora::Exit::ETriggerLevel::eProblematicEvent);
}
{
SysAssert(p__cxa_throw, "NST");
p__cxa_throw(pException, pInfo, fDtor);
}
}
#if defined(AURORA_PLATFORM_LINUX)
static _Unwind_Reason_Code __au_Unwind_RaiseException(void *pException, std::type_info *pInfo, struct _Unwind_Exception *pUnwind)
{
if (Grug::IsGrug())
{
SysAssert(p_Unwind_RaiseException, "URE");
return (_Unwind_Reason_Code)p_Unwind_RaiseException(pUnwind);
}
{
AU_DEBUG_MEMCRUNCH;
auto trace = GetStackTrace();
if (gRuntimeConfig.debug.bPrintExceptionStackTracesOut)
{
ReportException(pException, pInfo, trace, [&](const AuString &str)
{
AuLogWarn("Local Linux Exception: 0x{:x}, {}", AuUInt(pException), str.c_str());
AuLogWarn("{}", StringifyStackTrace(trace));
});
}
else
{
ReportException(pException, pInfo, trace);
}
AuExit::PostLevel(AuThreads::GetThread(), Aurora::Exit::ETriggerLevel::eProblematicEvent);
}
{
SysAssert(p_Unwind_RaiseException, "URE");
return (_Unwind_Reason_Code)p_Unwind_RaiseException(pUnwind);
}
}
#endif
}
AUKN_SYM void AU_NORETURN __au_cxa_throw(void *pException, std::type_info *pInfo, void (*fDtor)(void *pThis))
{
Aurora::Debug::__au_cxa_throw(pException, pInfo, fDtor);
}
#if defined(AURORA_PLATFORM_LINUX)
AUKN_SYM extern "C" _Unwind_Reason_Code _au_Unwind_RaiseException(struct _Unwind_Exception *pUnwind)
{
_Unwind_Exception *exception_header = pUnwind;
auto pException = (void **)(&pUnwind[1]);
#if defined(DEBUG_ABI_ALPHA)
auto pInfo = *(std::type_info **)((char *)pUnwind - 80);
// TODO: Test for clangs termination handler to somewhat verify that we are parsing a known structure layout
#else
std::type_info *pInfo { nullptr };
#endif
return Aurora::Debug::__au_Unwind_RaiseException(pException, pInfo, pUnwind);
}
#endif

View File

@ -7,4 +7,8 @@
***/
#pragma once
namespace Aurora::Debug
{
void InitUNIX();
void DeinitSignalHandlers();
}

View File

@ -88,8 +88,8 @@ namespace Aurora::Debug
try
{
Grug::GrugFlushFlushs();
Grug::GrugFlushWrites();
Grug::GrugFlushFlushs();
}
catch (...)
{
@ -126,6 +126,8 @@ namespace Aurora::Debug
#if defined(AURORA_IS_MODERNNT_DERIVED)
Win32Terminate();
#elif defined(AURORA_IS_POSIX_DERIVED)
PosixTerminate();
#else
#if defined(AURORA_COMPILER_GCC) || defined(AURORA_COMPILER_CLANG)
__builtin_trap();

View File

@ -86,6 +86,11 @@ namespace Aurora::Debug
return DumpContext((unw_context_t *)&uc);
}
StackTrace DumpContext(void *pContext)
{
return DumpContext((unw_context_t *)pContext);
}
StackTrace PlatformWalkCallStack()
{
#if 0

View File

@ -13,5 +13,7 @@ namespace Aurora::Debug
{
StackTrace DumpContext(ucontext_t &uc);
StackTrace DumpContext(void *pContext);
StackTrace PlatformWalkCallStack();
}

View File

@ -16,6 +16,11 @@ namespace Aurora::Exit
PostLevel(AuThreads::GetThread(), Exit::ETriggerLevel::eSigTerminate);
}
static void SendExitNowSignal(Grug::Arrow *)
{
PostLevel(AuThreads::GetThread(), Exit::ETriggerLevel::eSigQuitNow);
}
static void HandleSigTerminate(int sig)
{
static Grug::Arrow arrow;
@ -26,7 +31,7 @@ namespace Aurora::Exit
}
else
{
Grug::HurlArrow(&arrow, SendExitSignal, {});
Grug::HurlArrow(&arrow, SendExitNowSignal, {});
Grug::ArrowWait(&arrow);
}
}
@ -41,7 +46,8 @@ namespace Aurora::Exit
sigemptyset(&action.sa_mask);
sigaction(SIGINT, &action, nullptr);
//sigaction(SIGTERM, &action, nullptr);
sigaction(SIGTERM, &action, nullptr);
sigaction(SIGTSTP, &action, nullptr);
}
void DeinitUnix()
@ -54,6 +60,7 @@ namespace Aurora::Exit
sigemptyset(&action.sa_mask);
sigaction(SIGINT, &action, nullptr);
//sigaction(SIGTERM, &action, nullptr);
sigaction(SIGTERM, &action, nullptr);
sigaction(SIGTSTP, &action, nullptr);
}
}

View File

@ -32,7 +32,8 @@ namespace Aurora::Exit
{
static AuMutex gMutex;
static AuList<AuTuple<AuSPtr<IExitSubscriber>, ETriggerLevel>> gTriggerSubscribers;
static bool gIsAppRunning {true};
static bool gIsAppRunning { true };
static bool gIsAppForceTerminating { false };
static void DispatchHandlersForThread(AuThreads::IAuroraThread *pThread, ETriggerLevel level)
{
@ -83,11 +84,16 @@ namespace Aurora::Exit
//
bOldTerminatingValue = gIsAppRunning;
if (isTerminate || level == ETriggerLevel::eSigTerminate)
if (isTerminate || level == ETriggerLevel::eSigTerminate || level == ETriggerLevel::eSigQuitNow)
{
gIsAppRunning = false;
}
if (level == ETriggerLevel::eSigQuitNow)
{
gIsAppForceTerminating = true;
}
static AuUInt32 gProblemCounter = {};
// Mitigate reused stack, nested try/catch, spam
@ -134,18 +140,25 @@ namespace Aurora::Exit
gHasSentTerminate |= isTerminate;
}
if (gIsAppForceTerminating)
{
gHasCanceled = false;
}
if ((level == ETriggerLevel::eSigTerminate && !gHasCanceled) ||
level == ETriggerLevel::eFatalException ||
level == ETriggerLevel::eSafeTermination)
level == ETriggerLevel::eSafeTermination||
level == ETriggerLevel::eSigQuitNow)
{
UnsafeProcessShutdownHook();
}
// Force exit after calling the subscribers, should the level be eSigTerminate
if (level == ETriggerLevel::eSigTerminate)
if (level == ETriggerLevel::eSigTerminate ||
level == ETriggerLevel::eSigQuitNow)
{
// HACK:
if (gHasCanceled)
if (gHasCanceled && !gIsAppForceTerminating)
{
gIsAppRunning = bOldTerminatingValue;
}
@ -178,7 +191,7 @@ namespace Aurora::Exit
AUKN_SYM bool IsAppRunning()
{
return gIsAppRunning;
return gIsAppRunning && !gIsAppForceTerminating;
}
AUKN_SYM void CancelExit()
@ -194,6 +207,11 @@ namespace Aurora::Exit
PostLevel(AuThreads::GetThread(), Exit::ETriggerLevel::eSigTerminate);
}
static void SendExitNowSignal(Grug::Arrow *)
{
PostLevel(AuThreads::GetThread(), Exit::ETriggerLevel::eSigQuitNow);
}
static void SendTerminateSignalAndBlock()
{
static Grug::Arrow arrow;
@ -209,7 +227,14 @@ namespace Aurora::Exit
{
Exit::gHasCanceled = false;
//SendTerminateSignalAndBlock();// for some reason we aren't getting win32 console flushes **reliably** :(
if (ctrlType == CTRL_C_EVENT)
{
SendExitSignal(nullptr);
}
else
{
SendExitNowSignal(nullptr);
}
return !AuExchange(Exit::gHasCanceled, false);
}

View File

@ -60,7 +60,7 @@ namespace Aurora::IO::Adapters
this->SignalComplete();
}
void OnFailure()
void OnFailure() override
{
this->bInProgress = false;
this->Reset();

View File

@ -38,7 +38,7 @@ namespace Aurora::IO::Net
// TODO: we really need to make a general purpose AuAsync IO pool and generic resolver replacer/hooking interface for net services.
static auto GetGAIAsyncIOSignal()
{
return SIGUSR1 + gRuntimeConfig.linuxConfig.uSignalGAIOWorkerThreadDone;
return gRuntimeConfig.linuxConfig.uSignalGAIOWorkerThreadDone;
}
ThreadLocalCaughtCompletion::ThreadLocalCaughtCompletion(NetResolver *pParent) :
@ -100,7 +100,7 @@ namespace Aurora::IO::Net
NetResolver::NetResolver(const AuSPtr<INetWorker> &pWorker) :
pWorker_(pWorker)
{
this->pEvent = AuLoop::NewLSEvent(false, false);
this->pEvent = AuLoop::NewLSEventSlow(false, false);
}
NetResolver::NetResolver(const AuSPtr<INetWorker> &pWorker,
@ -108,7 +108,7 @@ namespace Aurora::IO::Net
pCompletion_(pCompletion),
pWorker_(pWorker)
{
this->pEvent = AuLoop::NewLSEvent(false, false);
this->pEvent = AuLoop::NewLSEventSlow(false, false);
}
NetResolver::~NetResolver()

View File

@ -75,23 +75,7 @@ namespace Aurora::IO::Net
if (!this->bDatagramMode)
{
AuLoop::ILSEvent *optEvent {};
if (this->pCompletionGroup_)
{
if (auto pLoopSource = this->pCompletionGroup_->GetTriggerLoopSource())
{
optEvent = AuStaticCast<Loop::LSEvent>(pLoopSource).get();
}
}
if (!optEvent)
{
if (auto pWaitable = this->pWaitable)
{
optEvent = pWaitable.get();
}
}
AuLoop::ILSEvent *optEvent { this->GetAlertable() };
if (!UNIX::LinuxOverlappedSubmitRead(this->GetSocket(), 0, this, optEvent, true))
{
@ -161,23 +145,7 @@ namespace Aurora::IO::Net
if (!this->bDatagramMode)
{
AuLoop::ILSEvent *optEvent {};
if (this->pCompletionGroup_)
{
if (auto pLoopSource = this->pCompletionGroup_->GetTriggerLoopSource())
{
optEvent = AuStaticCast<Loop::LSEvent>(pLoopSource).get();
}
}
if (!optEvent)
{
if (auto pWaitable = this->pWaitable)
{
optEvent = pWaitable.get();
}
}
AuLoop::ILSEvent *optEvent { this->GetAlertable() };
if (!UNIX::LinuxOverlappedSubmitWrite(this->GetSocket(), 0, this, optEvent))
{
@ -345,7 +313,11 @@ namespace Aurora::IO::Net
return pWaitable;
}
return this->pWaitable = AuLoop::NewLSEventSlow(false, true);
if (auto pSocket = this->pSocket)
{
return AuStaticCast<AuLoop::LSEvent>(pSocket->ToWorkerEx()->ToEvent());
}
//return this->pWaitable = AuLoop::NewLSEventSlow(false, true);
}
return {};
@ -417,28 +389,30 @@ namespace Aurora::IO::Net
return this->pSocket->ToPlatformHandle();
}
int LinuxAsyncNetworkTransaction::GetAlertable()
AuLoop::ILSEvent *LinuxAsyncNetworkTransaction::GetAlertable()
{
if (this->pCompletionGroup_)
{
auto pLoopSource = this->pCompletionGroup_->GetTriggerLoopSource();
if (!pLoopSource)
if (pLoopSource)
{
return -1;
return AuStaticCast<Loop::LSEvent>(pLoopSource).get();
}
return (int)AuStaticCast<Loop::LSEvent>(pLoopSource)->GetHandle();
}
else
{
if (auto pWaitable = this->pWaitable)
{
return AuStaticCast<AuLoop::LSEvent>(pWaitable).get();
}
if (auto pSocket = this->pSocket)
{
return (int)AuStaticCast<AuLoop::LSEvent>(pSocket->ToWorkerEx()->ToEvent())->GetHandle();
}
else
{
return -1;
return AuStaticCast<AuLoop::LSEvent>(pSocket->ToWorkerEx()->ToEvent()).get();
}
}
return nullptr;
}
}

View File

@ -62,7 +62,7 @@ namespace Aurora::IO::Net
void DispatchCb(AuUInt32 len);
int GetSocket();
int GetAlertable();
AuLoop::ILSEvent *GetAlertable();
bool TranslateLastError(bool bReturnValue);

View File

@ -12,11 +12,6 @@
#include <unistd.h>
#include <Source/IO/FS/FS.hpp>
namespace Aurora::Process
{
void PosixForkResetLocks();
}
namespace Aurora::Processes
{
static void UnixOpenAsyncThread(AuString uri, bool bType)
@ -65,7 +60,8 @@ namespace Aurora::Processes
{
setsid();
AuProcess::PosixForkResetLocks();
PosixDoForkHooks();
auto optStringA = AuProcess::EnvironmentGetOne("container");
auto optStringB = AuProcess::EnvironmentGetOne("AURORA_RUNTIME_USE_GDBUS_BIN_TO_PORTAL");
bool bIsFireJail = optStringA && optStringA.Value() == "firejail";

View File

@ -46,11 +46,6 @@
#include <sched.h>
#endif
namespace Aurora::Process
{
void PosixForkResetLocks();
}
namespace Aurora::Processes
{
static AuRWLock gRWLock;
@ -566,7 +561,7 @@ namespace Aurora::Processes
void ProcessImpl::ForkMain()
{
AuProcess::PosixForkResetLocks();
PosixDoForkHooks();
{
::dup2(this->pipeStdIn_[0], STDIN_FILENO);