Plasma Engine  2.0
Loading...
Searching...
No Matches
CrashHandler_Posix.h
1#include <Foundation/FoundationInternal.h>
2PL_FOUNDATION_INTERNAL_HEADER
3
4#include <Foundation/Logging/Log.h>
5#include <Foundation/System/CrashHandler.h>
6#include <Foundation/System/MiniDumpUtils.h>
7#include <Foundation/System/StackTracer.h>
8
9#include <csignal>
10#include <cxxabi.h>
11#include <unistd.h>
12
13static void PrintHelper(const char* szString)
14{
15 plLog::Printf("%s", szString);
16}
17
18static void plCrashHandlerFunc() noexcept
19{
20 if (plCrashHandler::GetCrashHandler() != nullptr)
21 {
22 plCrashHandler::GetCrashHandler()->HandleCrash(nullptr);
23 }
24
25 // restore the original signal handler for the abort signal and raise one so the kernel can do a core dump
26 std::signal(SIGABRT, SIG_DFL);
27 std::raise(SIGABRT);
28}
29
30static void plSignalHandler(int signum)
31{
32 plLog::Printf("***Unhandled Signal:***\n");
33 switch (signum)
34 {
35 case SIGINT:
36 plLog::Printf("Signal SIGINT: interrupt\n");
37 break;
38 case SIGILL:
39 plLog::Printf("Signal SIGILL: illegal instruction - invalid function image\n");
40 break;
41 case SIGFPE:
42 plLog::Printf("Signal SIGFPE: floating point exception\n");
43 break;
44 case SIGSEGV:
45 plLog::Printf("Signal SIGSEGV: segment violation\n");
46 break;
47 case SIGTERM:
48 plLog::Printf("Signal SIGTERM: Software termination signal from kill\n");
49 break;
50 case SIGABRT:
51 plLog::Printf("Signal SIGABRT: abnormal termination triggered by abort call\n");
52 break;
53 default:
54 plLog::Printf("Signal %i: unknown signal\n", signal);
55 break;
56 }
57
58 if (plCrashHandler::GetCrashHandler() != nullptr)
59 {
60 plCrashHandler::GetCrashHandler()->HandleCrash(nullptr);
61 }
62
63 // forward the signal back to the OS so that it can write a core dump
64 std::signal(signum, SIG_DFL);
65 kill(getpid(), signum);
66}
67
68void plCrashHandler::SetCrashHandler(plCrashHandler* pHandler)
69{
70 s_pActiveHandler = pHandler;
71
72 if (s_pActiveHandler != nullptr)
73 {
74 std::signal(SIGINT, plSignalHandler);
75 std::signal(SIGILL, plSignalHandler);
76 std::signal(SIGFPE, plSignalHandler);
77 std::signal(SIGSEGV, plSignalHandler);
78 std::signal(SIGTERM, plSignalHandler);
79 std::signal(SIGABRT, plSignalHandler);
80 std::set_terminate(plCrashHandlerFunc);
81 }
82 else
83 {
84 std::signal(SIGINT, nullptr);
85 std::signal(SIGILL, nullptr);
86 std::signal(SIGFPE, nullptr);
87 std::signal(SIGSEGV, nullptr);
88 std::signal(SIGTERM, nullptr);
89 std::signal(SIGABRT, nullptr);
90 std::set_terminate(nullptr);
91 }
92}
93
94bool plCrashHandler_WriteMiniDump::WriteOwnProcessMiniDump(void* pOsSpecificData)
95{
96 return false;
97}
98
99void plCrashHandler_WriteMiniDump::PrintStackTrace(void* pOsSpecificData)
100{
101 plLog::Printf("***Unhandled Exception:***\n");
102
103 // plLog::Printf exception type
104 if (std::type_info* type = abi::__cxa_current_exception_type())
105 {
106 if (const char* szName = type->name())
107 {
108 int status = -1;
109 // Try to print nice name
110 if (char* szNiceName = abi::__cxa_demangle(szName, 0, 0, &status))
111 plLog::Printf("Exception: %s\n", szNiceName);
112 else
113 plLog::Printf("Exception: %s\n", szName);
114 }
115 }
116
117 {
118 plLog::Printf("\n\n***Stack Trace:***\n");
119
120 void* pBuffer[64];
121 plArrayPtr<void*> tempTrace(pBuffer);
122 const plUInt32 uiNumTraces = plStackTracer::GetStackTrace(tempTrace);
123
124 plStackTracer::ResolveStackTrace(tempTrace.GetSubArray(0, uiNumTraces), &PrintHelper);
125 }
126}
This class encapsulates an array and it's size. It is recommended to use this class instead of plain ...
Definition ArrayPtr.h:37
Helper class to manage the top level exception handler.
Definition CrashHandler.h:21
static void Printf(const char *szFormat,...)
Calls low-level OS functionality to print a string to the typical outputs. Forwards to Print.
Definition Log.cpp:271
static void ResolveStackTrace(const plArrayPtr< void * > &trace, PrintFunc printFunc)
Print a stack trace.
Definition StackTracer_NoImpl.h:12
static plUInt32 GetStackTrace(plArrayPtr< void * > &ref_trace, void *pContext=nullptr)
Captures the current stack trace.
Definition StackTracer_NoImpl.h:7