libcruft-util/cruft/util/debug/crash_posix.cpp

75 lines
1.8 KiB
C++
Raw Normal View History

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2019, Danny Robson <danny@nerdcruft.net>
*/
#include "crash.hpp"
#include "../backtrace.hpp"
#include "../posix/except.hpp"
#include "../map/fixed.hpp"
#include <signal.h>
#include <iostream>
#include <cstring>
///////////////////////////////////////////////////////////////////////////////
static constexpr
int to_handle[] = {
SIGBUS,
SIGFPE,
SIGILL,
SIGSEGV,
SIGABRT,
};
auto constexpr handled_count = std::size (to_handle);
cruft::map::fixed<handled_count, int, struct sigaction> s_old_handlers;
//-----------------------------------------------------------------------------
void dumping_handler (int sig, siginfo_t *info, void *ucontext)
{
std::clog << cruft::backtrace () << '\n';
// Forward the signal to the previously registered handler
auto const next_handler = s_old_handlers.at (sig);
if (next_handler.sa_flags & SA_SIGINFO)
next_handler.sa_sigaction (sig, info, ucontext);
else
next_handler.sa_handler (sig);
}
///////////////////////////////////////////////////////////////////////////////
void
cruft::debug::init_crash_handler ()
{
// Keep this disabled for the time being as most projects we're using
// employ breakpad which has better functionality.
#if 0
struct sigaction new_handler {};
memset (&new_handler, 0, sizeof (new_handler));
new_handler.sa_flags = SA_SIGINFO;
new_handler.sa_sigaction = dumping_handler;
for (auto const sigid: to_handle) {
cruft::posix::error::try_code (
sigaction (
sigid,
&new_handler,
&s_old_handlers[sigid]
)
);
}
#endif
}