Merge pull request #6441 from pollend/feature/5886-add-unhandled-exception-support
feature: add Exception Handler support for unix
This commit is contained in:
@@ -98,7 +98,6 @@
|
||||
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
|
||||
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
|
||||
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 1
|
||||
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 0
|
||||
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
|
||||
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
|
||||
#define AZ_TRAIT_USE_WINDOWS_FILE_API 0
|
||||
|
||||
@@ -6,74 +6,121 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Debug/StackTracer.h>
|
||||
#include <AzCore/Debug/TraceMessageBus.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace AZ::Debug::Platform
|
||||
namespace AZ::Debug
|
||||
{
|
||||
#if defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
bool performDebuggerDetection()
|
||||
void ExceptionHandler(int signal);
|
||||
#endif
|
||||
|
||||
constexpr int MaxMessageLength = 4096;
|
||||
constexpr int MaxStackLines = 100;
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
AZ::IO::SystemFile processStatusFile;
|
||||
if (!processStatusFile.Open("/proc/self/status", AZ::IO::SystemFile::SF_OPEN_READ_ONLY))
|
||||
#if defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
bool performDebuggerDetection()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[4096];
|
||||
AZ::IO::SystemFile::SizeType numRead = processStatusFile.Read(sizeof(buffer), buffer);
|
||||
|
||||
const AZStd::string_view processStatusView(buffer, buffer + numRead);
|
||||
constexpr AZStd::string_view tracerPidString = "TracerPid:";
|
||||
const size_t tracerPidOffset = processStatusView.find(tracerPidString);
|
||||
if (tracerPidOffset == AZStd::string_view::npos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (size_t i = tracerPidOffset + tracerPidString.length(); i < numRead; ++i)
|
||||
{
|
||||
if (!::isspace(processStatusView[i]))
|
||||
AZ::IO::SystemFile processStatusFile;
|
||||
if (!processStatusFile.Open("/proc/self/status", AZ::IO::SystemFile::SF_OPEN_READ_ONLY))
|
||||
{
|
||||
return processStatusView[i] != '0';
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[MaxMessageLength];
|
||||
AZ::IO::SystemFile::SizeType numRead = processStatusFile.Read(sizeof(buffer), buffer);
|
||||
|
||||
const AZStd::string_view processStatusView(buffer, buffer + numRead);
|
||||
constexpr AZStd::string_view tracerPidString = "TracerPid:";
|
||||
const size_t tracerPidOffset = processStatusView.find(tracerPidString);
|
||||
if (tracerPidOffset == AZStd::string_view::npos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (size_t i = tracerPidOffset + tracerPidString.length(); i < numRead; ++i)
|
||||
{
|
||||
if (processStatusView[i] != ' ')
|
||||
{
|
||||
return processStatusView[i] != '0';
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsDebuggerPresent()
|
||||
{
|
||||
static bool s_detectionPerformed = false;
|
||||
static bool s_debuggerDetected = false;
|
||||
if (!s_detectionPerformed)
|
||||
{
|
||||
s_debuggerDetected = performDebuggerDetection();
|
||||
s_detectionPerformed = true;
|
||||
}
|
||||
return s_debuggerDetected;
|
||||
}
|
||||
|
||||
bool AttachDebugger()
|
||||
{
|
||||
// Not supported yet
|
||||
AZ_Assert(false, "AttachDebugger() is not supported for Unix platform yet");
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsDebuggerPresent()
|
||||
{
|
||||
static bool s_detectionPerformed = false;
|
||||
static bool s_debuggerDetected = false;
|
||||
if (!s_detectionPerformed)
|
||||
void DebugBreak()
|
||||
{
|
||||
s_debuggerDetected = performDebuggerDetection();
|
||||
s_detectionPerformed = true;
|
||||
raise(SIGINT);
|
||||
}
|
||||
return s_debuggerDetected;
|
||||
}
|
||||
|
||||
bool AttachDebugger()
|
||||
{
|
||||
// Not supported yet
|
||||
AZ_Assert(false, "AttachDebugger() is not supported for Unix platform yet");
|
||||
return false;
|
||||
}
|
||||
|
||||
void HandleExceptions(bool)
|
||||
{}
|
||||
|
||||
void DebugBreak()
|
||||
{
|
||||
raise(SIGINT);
|
||||
}
|
||||
#endif // AZ_ENABLE_DEBUG_TOOLS
|
||||
|
||||
void Terminate(int exitCode)
|
||||
void Terminate(int exitCode)
|
||||
{
|
||||
_exit(exitCode);
|
||||
}
|
||||
} // namespace Platform
|
||||
|
||||
#if defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
void ExceptionHandler(int signal)
|
||||
{
|
||||
_exit(exitCode);
|
||||
char message[MaxMessageLength];
|
||||
// Trace::RawOutput
|
||||
Debug::Trace::Instance().RawOutput(nullptr, "==================================================================\n");
|
||||
azsnprintf(message, MaxMessageLength, "Error: signal %s: \n", strsignal(signal));
|
||||
Debug::Trace::Instance().RawOutput(nullptr, message);
|
||||
|
||||
StackFrame frames[MaxStackLines];
|
||||
SymbolStorage::StackLine stackLines[MaxStackLines];
|
||||
SymbolStorage decoder;
|
||||
const unsigned int numberOfFrames = StackRecorder::Record(frames, MaxStackLines);
|
||||
decoder.DecodeFrames(frames, numberOfFrames, stackLines);
|
||||
for (int i = 0; i < numberOfFrames; ++i)
|
||||
{
|
||||
azsnprintf(message, MaxMessageLength, "%s \n", stackLines[i]);
|
||||
Debug::Trace::Instance().RawOutput(nullptr, message);
|
||||
}
|
||||
Debug::Trace::Instance().RawOutput(nullptr, "==================================================================\n");
|
||||
}
|
||||
} // namespace AZ::Debug::Platform
|
||||
#endif
|
||||
|
||||
} // namespace AZ::Debug
|
||||
|
||||
@@ -98,7 +98,6 @@
|
||||
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
|
||||
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
|
||||
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
|
||||
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
|
||||
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
|
||||
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
|
||||
#define AZ_TRAIT_USE_WINDOWS_FILE_API 0
|
||||
|
||||
@@ -98,7 +98,6 @@
|
||||
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
|
||||
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
|
||||
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
|
||||
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
|
||||
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
|
||||
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
|
||||
#define AZ_TRAIT_USE_WINDOWS_FILE_API 0
|
||||
|
||||
@@ -98,7 +98,6 @@
|
||||
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE INVALID_RETURN_VALUE
|
||||
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 1
|
||||
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
|
||||
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 0
|
||||
#define AZ_TRAIT_USE_POSIX_STRERROR_R 0
|
||||
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 1
|
||||
#define AZ_TRAIT_USE_WINDOWS_FILE_API 1
|
||||
|
||||
@@ -99,7 +99,6 @@
|
||||
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
|
||||
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
|
||||
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
|
||||
#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
|
||||
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
|
||||
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
|
||||
#define AZ_TRAIT_USE_WINDOWS_FILE_API 0
|
||||
|
||||
Reference in New Issue
Block a user