Merge pull request #2 from KjellKod/signal_improved_handling2

JuceTesting shows that all signalhandling should be installed per thread
This commit is contained in:
Kjell Hedstrom 2015-02-02 21:44:24 -07:00
commit e71b5fc7c0
3 changed files with 35 additions and 33 deletions

View File

@ -30,6 +30,7 @@ namespace {
std::atomic<bool> gBlockForFatal {true}; std::atomic<bool> gBlockForFatal {true};
void* g_vector_exception_handler = nullptr; void* g_vector_exception_handler = nullptr;
LPTOP_LEVEL_EXCEPTION_FILTER g_previous_unexpected_exception_handler = nullptr; LPTOP_LEVEL_EXCEPTION_FILTER g_previous_unexpected_exception_handler = nullptr;
g2_thread_local bool g_installed_thread_signal_handler = false;
@ -179,11 +180,6 @@ void exitWithDefaultSignalHandler(const LEVELS& level, g2::SignalType fatal_sign
void installSignalHandler() { void installSignalHandler() {
g2::installSignalHandlerForThread(); g2::installSignalHandlerForThread();
if (SIG_ERR == signal(SIGABRT, signalHandler))
perror("signal - SIGABRT");
if (SIG_ERR == signal(SIGTERM, signalHandler))
perror("signal - SIGTERM");
} }
@ -195,13 +191,19 @@ void installSignalHandler() {
/// you can also use this function call, per thread so make sure these three /// you can also use this function call, per thread so make sure these three
/// fatal signals are covered in your thread (even if you don't do a LOG(...) call /// fatal signals are covered in your thread (even if you don't do a LOG(...) call
void installSignalHandlerForThread() { void installSignalHandlerForThread() {
if (SIG_ERR == signal(SIGFPE, signalHandler)) if (!g_installed_thread_signal_handler) {
perror("signal - SIGFPE"); g_installed_thread_signal_handler = true;
if (SIG_ERR == signal(SIGSEGV, signalHandler)) if (SIG_ERR == signal(SIGTERM, signalHandler))
perror("signal - SIGSEGV"); perror("signal - SIGTERM");
if (SIG_ERR == signal(SIGILL, signalHandler)) if (SIG_ERR == signal(SIGABRT, signalHandler))
perror("signal - SIGILL"); perror("signal - SIGABRT");
if (SIG_ERR == signal(SIGFPE, signalHandler))
perror("signal - SIGFPE");
if (SIG_ERR == signal(SIGSEGV, signalHandler))
perror("signal - SIGSEGV");
if (SIG_ERR == signal(SIGILL, signalHandler))
perror("signal - SIGILL");
}
} }
void installCrashHandler() { void installCrashHandler() {

View File

@ -32,10 +32,9 @@
#define g2_MAP_PAIR_STRINGIFY(x) {x, #x} #define g2_MAP_PAIR_STRINGIFY(x) {x, #x}
#define thread_local __declspec(thread)
namespace { namespace {
thread_local bool g_thread_local_recursive_crash_check = false; g2_thread_local bool g_thread_local_recursive_crash_check = false;
const std::map<g2::SignalType, std::string> kExceptionsAsText = { const std::map<g2::SignalType, std::string> kExceptionsAsText = {
g2_MAP_PAIR_STRINGIFY(EXCEPTION_ACCESS_VIOLATION) g2_MAP_PAIR_STRINGIFY(EXCEPTION_ACCESS_VIOLATION)
@ -189,27 +188,26 @@ std::string stackdump(CONTEXT* context) {
static std::mutex m; static std::mutex m;
std::lock_guard<std::mutex> lock(m); std::lock_guard<std::mutex> lock(m);
{
const BOOL kLoadSymModules = TRUE;
const auto initialized = SymInitialize(GetCurrentProcess(), nullptr, kLoadSymModules);
if (TRUE != initialized) {
return{ "Error: Cannot call SymInitialize(...) for retrieving symbols in stack" };
}
const BOOL kLoadSymModules = TRUE; std::shared_ptr<void> RaiiSymCleaner(nullptr, [&](void*) {
const auto initialized = SymInitialize(GetCurrentProcess(), nullptr, kLoadSymModules); SymCleanup(GetCurrentProcess());
if (TRUE != initialized) { }); // Raii sym cleanup
return {"Error: Cannot call SymInitialize(...) for retrieving symbols in stack"};
const size_t kmax_frame_dump_size = 64;
std::vector<uint64_t> frame_pointers(kmax_frame_dump_size);
// C++11: size set and values are zeroed
assert(frame_pointers.size() == kmax_frame_dump_size);
captureStackTrace(context, frame_pointers);
return convertFramesToText(frame_pointers);
} }
std::shared_ptr<void> RaiiSymCleaner(nullptr, [&](void*) {
SymCleanup(GetCurrentProcess());
}); // Raii sym cleanup
const size_t kmax_frame_dump_size = 64;
std::vector<uint64_t> frame_pointers(kmax_frame_dump_size);
// C++11: size set and values are zeroed
assert(frame_pointers.size() == kmax_frame_dump_size);
captureStackTrace(context, frame_pointers);
return convertFramesToText(frame_pointers);
} }
} // stacktrace } // stacktrace

View File

@ -17,6 +17,8 @@
#error "stacktrace_win.cpp used but not on a windows system" #error "stacktrace_win.cpp used but not on a windows system"
#endif #endif
#define g2_thread_local __declspec(thread)
#include <string> #include <string>
#include <windows.h> #include <windows.h>
#include "crashhandler.hpp" #include "crashhandler.hpp"