Commit 16eb78da authored by Richard Gobeille's avatar Richard Gobeille
Browse files

loguru: Windows support for signal handler stuff

parent a91e9f3f
......@@ -234,9 +234,17 @@ void engineSetupLogging(int &argc, char **argv)
loguru::set_thread_name("main");
loguru::set_verbosity_to_name_callback(&engineVerbosityCallback);
loguru::add_callback(CB_ENGINE, engineLogCallback, nullptr, LOG_ENGINE_MAX);
loguru::set_fatal_handler([](const loguru::Message& UNUSED(message)){
UNREFERENCED_CONST_PARAMETER(message);
#ifdef DEBUGGINGAIDS
debug_break();
#endif
app_crashhandler();
Bexit(EXIT_FAILURE);
});
loguru::Options initopts;
initopts.verbosity_flag = nullptr;
initopts.signal_options.unsafe_signal_handler = true;
loguru::init(argc, argv, initopts);
}
......
......@@ -54,13 +54,14 @@
#define LOG_USER 0
#endif
#include <signal.h>
#ifdef _WIN32
#include <direct.h>
#include <share.h>
#define localtime_r(a, b) localtime_s(b, a) // No localtime_r with MSVC, but arguments are swapped for localtime_s
#else
#include <signal.h>
#include <sys/stat.h> // mkdir
#include <unistd.h> // STDERR_FILENO
#endif
......@@ -1962,49 +1963,25 @@ namespace loguru
// 8bodP' 88 YboodP 88 Y8 dP""""Yb 88ood8 8bodP'
// ----------------------------------------------------------------------------
#ifdef _WIN32
namespace loguru {
void install_signal_handlers(const SignalOptions& signal_options)
{
(void)signal_options;
// TODO: implement signal handlers on windows
}
} // namespace loguru
#else // _WIN32
namespace loguru
{
void write_to_stderr(const char* data, size_t size)
{
auto result = write(STDERR_FILENO, data, size);
(void)result; // Ignore errors.
}
void write_to_stderr(const char* data, size_t size);
void write_to_stderr(const char* data)
{
write_to_stderr(data, strlen(data));
}
void call_default_signal_handler(int signal_number)
{
struct sigaction sig_action;
memset(&sig_action, 0, sizeof(sig_action));
sigemptyset(&sig_action.sa_mask);
sig_action.sa_handler = SIG_DFL;
// Note: Explicitly ignore sigaction's return value.
// It's only used when setting up the signal handlers.
(void) sigaction(signal_number, &sig_action, NULL);
kill(getpid(), signal_number);
}
void call_default_signal_handler(int signal_number);
void signal_handler(int signal_number, siginfo_t*, void*)
void signal_handler(int signal_number)
{
const char* signal_name = "UNKNOWN SIGNAL";
if (signal_number == SIGABRT) { signal_name = "SIGABRT"; }
#ifndef _WIN32
if (signal_number == SIGBUS) { signal_name = "SIGBUS"; }
#endif
if (signal_number == SIGFPE) { signal_name = "SIGFPE"; }
if (signal_number == SIGILL) { signal_name = "SIGILL"; }
if (signal_number == SIGINT) { signal_name = "SIGINT"; }
......@@ -2057,6 +2034,78 @@ namespace loguru
call_default_signal_handler(signal_number);
}
} // namespace loguru
#ifdef _WIN32
namespace loguru
{
#ifdef _MSC_VER
_crt_signal_t default_handler[NSIG] = {};
#else
__p_sig_fn_t default_handler[NSIG] = {};
#endif
void write_to_stderr(const char* data, size_t size)
{
HANDLE hOut = GetStdHandle(STD_ERROR_HANDLE);
WriteFile(hOut, data, size, nullptr, nullptr);
}
void call_default_signal_handler(int signal_number)
{
if (default_handler[signal_number] && default_handler[signal_number] != SIG_ERR)
default_handler[signal_number](signal_number);
}
void install_signal_handlers(const SignalOptions& signal_options)
{
if (signal_options.sigabrt) {
CHECK_F((default_handler[SIGABRT] = signal(SIGABRT, signal_handler)) != SIG_ERR, "Failed to install handler for SIGABRT");
}
if (signal_options.sigfpe) {
CHECK_F((default_handler[SIGFPE] = signal(SIGFPE, signal_handler)) != SIG_ERR, "Failed to install handler for SIGFPE");
}
if (signal_options.sigill) {
CHECK_F((default_handler[SIGILL] = signal(SIGILL, signal_handler)) != SIG_ERR, "Failed to install handler for SIGILL");
}
if (signal_options.sigint) {
CHECK_F((default_handler[SIGINT] = signal(SIGINT, signal_handler)) != SIG_ERR, "Failed to install handler for SIGINT");
}
if (signal_options.sigsegv) {
CHECK_F((default_handler[SIGSEGV] = signal(SIGSEGV, signal_handler)) != SIG_ERR, "Failed to install handler for SIGSEGV");
}
if (signal_options.sigterm) {
CHECK_F((default_handler[SIGTERM] = signal(SIGTERM, signal_handler)) != SIG_ERR, "Failed to install handler for SIGTERM");
}
}
} // namespace loguru
#else // _WIN32
namespace loguru
{
void write_to_stderr(const char* data, size_t size)
{
auto result = write(STDERR_FILENO, data, size);
(void)result; // Ignore errors.
}
void call_default_signal_handler(int signal_number)
{
struct sigaction sig_action;
memset(&sig_action, 0, sizeof(sig_action));
sigemptyset(&sig_action.sa_mask);
sig_action.sa_handler = SIG_DFL;
// Note: Explicitly ignore sigaction's return value.
// It's only used when setting up the signal handlers.
(void) sigaction(signal_number, &sig_action, NULL);
kill(getpid(), signal_number);
}
void signal_handler(int signal_number, siginfo_t*, void*)
{
signal_handler(signal_number);
}
void install_signal_handlers(const SignalOptions& signal_options)
{
......@@ -2091,10 +2140,8 @@ namespace loguru
}
}
} // namespace loguru
#endif // _WIN32
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#elif defined(_MSC_VER)
......
......@@ -467,6 +467,14 @@ int main(int argc, char *argv[])
#endif
engineSetupAllocator();
#ifndef __ANDROID__
signal(SIGSEGV, sighandler);
signal(SIGILL, sighandler); /* clang -fcatch-undefined-behavior uses an ill. insn */
signal(SIGABRT, sighandler);
signal(SIGFPE, sighandler);
#endif
engineSetupLogging(argc, argv);
#if SDL_VERSION_ATLEAST(2, 0, 8)
......@@ -508,12 +516,7 @@ int main(int argc, char *argv[])
buildkeytranslationtable();
#ifndef __ANDROID__
signal(SIGSEGV, sighandler);
signal(SIGILL, sighandler); /* clang -fcatch-undefined-behavior uses an ill. insn */
signal(SIGABRT, sighandler);
signal(SIGFPE, sighandler);
#else
#ifdef __ANDROID__
SDL_SetEventFilter(sdlayer_mobilefilter, NULL);
#endif
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment