feat: Integrate cpptrace for enhanced crash reporting and stack trace generation

This commit is contained in:
2026-01-05 04:13:30 +00:00
parent ec7c3fd880
commit 40bf31964b
3 changed files with 32 additions and 1 deletions

View File

@@ -114,6 +114,7 @@ find_package(assimp CONFIG REQUIRED)
find_package(Bullet CONFIG REQUIRED)
find_package(Vorbis CONFIG REQUIRED)
find_package(glm CONFIG REQUIRED)
find_package(cpptrace REQUIRED)
if(BUILD_SDL3_APP)
add_executable(sdl3_app
@@ -154,7 +155,7 @@ if(BUILD_SDL3_APP)
src/services/impl/gui_renderer.cpp
)
target_include_directories(sdl3_app PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src")
target_link_libraries(sdl3_app PRIVATE ${SDL_TARGET} Vulkan::Vulkan lua::lua CLI11::CLI11 rapidjson assimp::assimp Bullet::Bullet glm::glm Vorbis::vorbisfile Vorbis::vorbis)
target_link_libraries(sdl3_app PRIVATE ${SDL_TARGET} Vulkan::Vulkan lua::lua CLI11::CLI11 rapidjson assimp::assimp Bullet::Bullet glm::glm Vorbis::vorbisfile Vorbis::vorbis cpptrace)
target_compile_definitions(sdl3_app PRIVATE SDL_MAIN_HANDLED)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/shaders")

View File

@@ -25,6 +25,7 @@ class SDL3CppConan(ConanFile):
self.requires("vulkan-headers/1.3.243.0")
self.requires("vulkan-memory-allocator/3.3.0")
self.requires("vulkan-validationlayers/1.3.243.0")
self.requires("cpptrace/1.0.4")
self.requires("ogg/1.3.5")
self.requires("theora/1.1.1")
self.requires("cli11/2.6.0")

View File

@@ -3,12 +3,28 @@
#include <chrono>
#include <sstream>
#include <cstring>
#include <cpptrace/cpptrace.hpp>
#include <unistd.h>
#include <filesystem>
#include <sys/resource.h>
namespace sdl3cpp::services::impl {
namespace {
constexpr int kSignalExitCodeBase = 128;
constexpr size_t kStackTraceSkipFrames = 3;
constexpr size_t kStackTraceMaxDepth = 64;
volatile sig_atomic_t crashHandlingInProgress = 0;
std::string BuildStackTrace() {
const auto trace = cpptrace::generate_trace(kStackTraceSkipFrames, kStackTraceMaxDepth);
if (trace.empty()) {
return {};
}
return trace.to_string();
}
}
// Static instance for signal handler
CrashRecoveryService* CrashRecoveryService::instance_ = nullptr;
@@ -111,6 +127,11 @@ std::string CrashRecoveryService::GetCrashReport() const {
}
void CrashRecoveryService::SignalHandler(int signal) {
if (crashHandlingInProgress != 0) {
_exit(kSignalExitCodeBase + signal);
}
crashHandlingInProgress = 1;
if (instance_) {
if (instance_->logger_) {
instance_->logger_->Trace("CrashRecoveryService", "SignalHandler",
@@ -118,6 +139,8 @@ void CrashRecoveryService::SignalHandler(int signal) {
}
instance_->HandleCrash(signal);
}
_exit(kSignalExitCodeBase + signal);
}
void CrashRecoveryService::SetupSignalHandlers() {
@@ -193,6 +216,12 @@ void CrashRecoveryService::HandleCrash(int signal) {
crashReport_ = ss.str();
const std::string stackTrace = BuildStackTrace();
if (!stackTrace.empty()) {
crashReport_ += "\n=== STACK TRACE ===\n";
crashReport_ += stackTrace;
}
logger_->Error("CrashRecoveryService::HandleCrash: " + crashReport_);
// Note: In a real implementation, you might want to: