feature: add Exception Handler support for unix

REF: https://github.com/o3de/o3de/issues/5886

Signed-off-by: Michael Pollind <mpollind@gmail.com>
monroegm-disable-blank-issue-2
Michael Pollind 4 years ago
parent da0a10bb4c
commit ada7c41a34

@ -6,15 +6,26 @@
*
*/
#include <AzCore/Debug/TraceMessageBus.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/std/string/string_view.h>
#include <ctype.h>
#include <execinfo.h>
#include <signal.h>
#include <unistd.h>
namespace AZ::Debug::Platform
namespace AZ::Debug
{
#if defined(AZ_ENABLE_DEBUG_TOOLS)
void ExceptionHandler(int signal);
#endif
constexpr int MaxMessageLength = 4096;
constexpr int MaxStackLines = 100;
namespace Platform
{
#if defined(AZ_ENABLE_DEBUG_TOOLS)
bool performDebuggerDetection()
{
@ -63,8 +74,25 @@ namespace AZ::Debug::Platform
return false;
}
void HandleExceptions(bool)
{}
void SignalHandler(int handler)
{
}
void HandleExceptions(bool isEnabled)
{
if (isEnabled)
{
signal(SIGSEGV, ExceptionHandler);
signal(SIGTRAP, ExceptionHandler);
signal(SIGILL, ExceptionHandler);
}
else
{
signal(SIGSEGV, SIG_DFL);
signal(SIGTRAP, SIG_DFL);
signal(SIGILL, SIG_DFL);
}
}
void DebugBreak()
{
@ -76,4 +104,31 @@ namespace AZ::Debug::Platform
{
_exit(exitCode);
}
} // namespace AZ::Debug::Platform
} // namespace Platform
#if defined(AZ_ENABLE_DEBUG_TOOLS)
void ExceptionHandler(int signal)
{
char message[MaxMessageLength];
Debug::Trace::Instance().Output(nullptr, "==================================================================\n");
azsnprintf(message, MaxMessageLength, "Error: signal %s: \n", strsignal(signal));
Debug::Trace::Instance().Output(nullptr, message);
void* buffers[MaxStackLines];
int numberBacktraceStrings = backtrace(buffers, MaxStackLines);
char** backtraceResults = backtrace_symbols(buffers, numberBacktraceStrings);
if (backtraceResults == nullptr)
{
Debug::Trace::Instance().Output(nullptr, "==================================================================\n");
return;
}
for (int j = 0; j < numberBacktraceStrings; j++)
{
Debug::Trace::Instance().Output(nullptr, backtraceResults[j]);
}
Debug::Trace::Instance().Output(nullptr, "==================================================================\n");
}
#endif
} // namespace AZ::Debug

@ -115,43 +115,6 @@ extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExce
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
#endif
#if AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
#include <execinfo.h>
#include <signal.h>
void CryEngineSignalHandler(int signal)
{
char resolvedPath[_MAX_PATH];
// it is assumed that @log@ points at the appropriate place (so for apple, to the user profile dir)
if (AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath("@log@/crash.log", resolvedPath, _MAX_PATH))
{
fprintf(stderr, "Crash Signal Handler - logged to %s\n", resolvedPath);
FILE* file = fopen(resolvedPath, "a");
if (file)
{
char sTime[128];
time_t ltime;
time(&ltime);
struct tm* today = localtime(&ltime);
strftime(sTime, 40, "<%Y-%m-%d %H:%M:%S> ", today);
fprintf(file, "%s: Error: signal %s:\n", sTime, strsignal(signal));
fflush(file);
void* array[100];
int s = backtrace(array, 100);
backtrace_symbols_fd(array, s, fileno(file));
fclose(file);
CryLogAlways("Successfully recorded crash file: '%s'", resolvedPath);
abort();
}
}
CryLogAlways("Could not record crash file...");
abort();
}
#endif // AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
//////////////////////////////////////////////////////////////////////////
#define DEFAULT_LOG_FILENAME "@log@/Log.txt"
@ -697,11 +660,6 @@ public:
/////////////////////////////////////////////////////////////////////////////////
bool CSystem::Init(const SSystemInitParams& startupParams)
{
#if AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
signal(SIGSEGV, CryEngineSignalHandler);
signal(SIGTRAP, CryEngineSignalHandler);
signal(SIGILL, CryEngineSignalHandler);
#endif // AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
// Temporary Fix for an issue accessing gEnv from this object instance. The gEnv is not resolving to the
// global gEnv, instead its resolving an some uninitialized gEnv elsewhere (NULL). Since gEnv is

Loading…
Cancel
Save