* @file
*
* This file implements functions related to the Unix crash signal handler.
*/
#include "cangjie/Driver/TempFileManager.h"
#include "cangjie/Macro/InvokeUtil.h"
#if (defined RELEASE)
#include "SignalUtil.h"
namespace {
constexpr size_t SIGNAL_STACK_SIZE = 8192;
constexpr size_t SIGNAL_NUM = 6;
constexpr int SIGNALS[SIGNAL_NUM] = {SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTRAP};
const std::vector<std::string> SIGNALS_STR = {"SIGABRT", "SIGBUS", "SIGFPE", "SIGILL", "SIGSEGV", "SIGTRAP"};
void SignalHandler(int signum)
{
Cangjie::Signal::ConcurrentSynchronousSignalHandler(signum);
}
}
static stack_t g_oldAltStack;
__attribute__((__used__)) static char g_altStackPointer[SIGNAL_STACK_SIZE] = {0};
namespace Cangjie {
void CreateAltSignalStack()
{
if (sigaltstack(nullptr, &g_oldAltStack) != 0 || (g_oldAltStack.ss_flags & SS_ONSTACK) != 0 ||
(g_oldAltStack.ss_sp && g_oldAltStack.ss_size >= SIGNAL_STACK_SIZE)) {
return;
}
stack_t sigstack;
sigstack.ss_sp = static_cast<void*>(g_altStackPointer);
sigstack.ss_size = SIGNAL_STACK_SIZE;
sigstack.ss_flags = 0;
if (sigaltstack(&sigstack, &g_oldAltStack) != 0) {
InternalError("Failed to create a backup stack for the thread.");
}
}
void RegisterCrashSignalHandler()
{
struct sigaction sa;
sa.sa_handler = SignalHandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_ONSTACK;
for (auto& sig : SIGNALS) {
if (sigaction(sig, &sa, nullptr) == -1) {
continue;
}
}
}
}
#else
#include <csignal>
#endif
namespace {
void SigintHandler(int signum)
{
Cangjie::TempFileManager::Instance().DeleteTempFilesSignalSafe();
_exit(signum + 128);
}
}
namespace Cangjie {
void RegisterCrtlCSignalHandler()
{
struct sigaction sa;
sa.sa_handler = SigintHandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
(void)sigaction(SIGINT, &sa, nullptr);
}
}