mirror of
https://github.com/NixOS/nix
synced 2025-06-24 22:11:15 +02:00
port crash-handler from lix to nix
It was first introduced in19e0ce2c03
In Nix we only register the crash handler in main instead of initNix, because library user may want to use their own crash handler. Sample output: Mar 12 08:38:06 eve nix[2303762]: Nix crashed. This is a bug. Please report this at https://github.com/NixOS/nix/issues with the following information included: Mar 12 08:38:06 eve nix[2303762]: Exception: nix::SysError: error: writing to file: Resource temporarily unavailable Mar 12 08:38:06 eve nix[2303762]: Stack trace: Mar 12 08:38:06 eve nix[2303762]: 0# 0x000000000076876A in nix 1# 0x00007FDA40E9F20A in /nix/store/2lhklm5aizx30qbw49acnrrzkj9lbmij-gcc-14-20241116-lib/lib/libstdc++.so.6 2# std::unexpected() in /nix/store/2lhklm5aizx30qbw49acnrrzkj9lbmij-gcc-14-20241116-lib/lib/libstdc++.so.6 3# 0x00007FDA40E9F487 in /nix/store/2lhklm5aizx30qbw49acnrrzkj9lbmij-gcc-14-20241116-lib/lib/libstdc++.so.6 4# nix::writeFull(int, std::basic_string_view<char, std::char_traits<char> >, bool) in /home/joerg/git/nix/inst/lib/libnixutil.so 5# nix::writeLine(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) in /home/joerg/git/nix/inst/lib/libnixutil.so 6# nix::JSONLogger::write(nlohmann::json_abi_v3_11_3::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::json_abi_v3_11_3::adl_serializer, std::vector<unsigned char, std::allocator<unsigned char> >, void> const&) in /home/joerg/git/nix/inst/lib/libnixutil.so 7# nix::JSONLogger::logEI(nix::ErrorInfo const&) in /home/joerg/git/nix/inst/lib/libnixutil.so 8# nix::Logger::logEI(nix::Verbosity, nix::ErrorInfo) in nix 9# nix::handleExceptions(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::function<void ()>) in /home/joerg/git/nix/inst/lib/libnixmain.so 10# 0x000000000087A563 in nix 11# 0x00007FDA40BD41FE in /nix/store/6q2mknq81cyscjmkv72fpcsvan56qhmg-glibc-2.40-66/lib/libc.so.6 12# __libc_start_main in /nix/store/6q2mknq81cyscjmkv72fpcsvan56qhmg-glibc-2.40-66/lib/libc.so.6 13# 0x00000000006F4DF5 in nix Co-authored-by: eldritch horrors <pennae@lix.systems> (cherry picked from commit163f94412a
)
This commit is contained in:
parent
616109a040
commit
b1f0f1c5a1
4 changed files with 82 additions and 0 deletions
67
src/nix/crash-handler.cc
Normal file
67
src/nix/crash-handler.cc
Normal file
|
@ -0,0 +1,67 @@
|
|||
#include "crash-handler.hh"
|
||||
#include "fmt.hh"
|
||||
#include "logging.hh"
|
||||
|
||||
#include <boost/core/demangle.hpp>
|
||||
#include <exception>
|
||||
#include <sstream>
|
||||
|
||||
// Darwin and FreeBSD stdenv do not define _GNU_SOURCE but do have _Unwind_Backtrace.
|
||||
#if __APPLE__ || __FreeBSD__
|
||||
# define BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED
|
||||
#endif
|
||||
|
||||
#include <boost/stacktrace/stacktrace.hpp>
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <syslog.h>
|
||||
#endif
|
||||
|
||||
namespace nix {
|
||||
|
||||
namespace {
|
||||
|
||||
void logFatal(std::string const & s)
|
||||
{
|
||||
writeToStderr(s + "\n");
|
||||
// std::string for guaranteed null termination
|
||||
#ifndef _WIN32
|
||||
syslog(LOG_CRIT, "%s", s.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
void onTerminate()
|
||||
{
|
||||
logFatal(
|
||||
"Nix crashed. This is a bug. Please report this at https://github.com/NixOS/nix/issues with the following information included:\n");
|
||||
try {
|
||||
std::exception_ptr eptr = std::current_exception();
|
||||
if (eptr) {
|
||||
std::rethrow_exception(eptr);
|
||||
} else {
|
||||
logFatal("std::terminate() called without exception");
|
||||
}
|
||||
} catch (const std::exception & ex) {
|
||||
logFatal(fmt("Exception: %s: %s", boost::core::demangle(typeid(ex).name()), ex.what()));
|
||||
} catch (...) {
|
||||
logFatal("Unknown exception!");
|
||||
}
|
||||
|
||||
logFatal("Stack trace:");
|
||||
std::stringstream ss;
|
||||
ss << boost::stacktrace::stacktrace();
|
||||
logFatal(ss.str());
|
||||
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
void registerCrashHandler()
|
||||
{
|
||||
// DO NOT use this for signals. Boost stacktrace is very much not
|
||||
// async-signal-safe, and in a world with ASLR, addr2line is pointless.
|
||||
//
|
||||
// If you want signals, set up a minidump system and do it out-of-process.
|
||||
std::set_terminate(onTerminate);
|
||||
}
|
||||
}
|
11
src/nix/crash-handler.hh
Normal file
11
src/nix/crash-handler.hh
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
/// @file Crash handler for Nix that prints back traces (hopefully in instances where it is not just going to crash the
|
||||
/// process itself).
|
||||
|
||||
namespace nix {
|
||||
|
||||
/** Registers the Nix crash handler for std::terminate (currently; will support more crashes later). See also
|
||||
* detectStackOverflow(). */
|
||||
void registerCrashHandler();
|
||||
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
#include "flake/flake.hh"
|
||||
#include "self-exe.hh"
|
||||
#include "json-utils.hh"
|
||||
#include "crash-handler.hh"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <regex>
|
||||
|
@ -354,6 +355,8 @@ void mainWrapped(int argc, char * * argv)
|
|||
{
|
||||
savedArgv = argv;
|
||||
|
||||
registerCrashHandler();
|
||||
|
||||
/* The chroot helper needs to be run before any threads have been
|
||||
started. */
|
||||
#ifndef _WIN32
|
||||
|
|
|
@ -77,6 +77,7 @@ nix_sources = [config_h] + files(
|
|||
'config-check.cc',
|
||||
'config.cc',
|
||||
'copy.cc',
|
||||
'crash-handler.cc',
|
||||
'derivation-add.cc',
|
||||
'derivation-show.cc',
|
||||
'derivation.cc',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue