Skip to content

Commit

Permalink
make stacktrace on terminate more detailed
Browse files Browse the repository at this point in the history
  • Loading branch information
StellaSmith committed Feb 11, 2024
1 parent ea5ff68 commit bb29d27
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 21 deletions.
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ find_package(EnTT CONFIG REQUIRED)
find_package(SDL2 CONFIG REQUIRED)
find_package(Boost CONFIG REQUIRED)
find_package(SDL2_image CONFIG REQUIRED)
find_package(range-v3 CONFIG REQUIRED)

add_subdirectory(external)

Expand Down Expand Up @@ -127,7 +128,11 @@ target_include_directories(little_game PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/inclu
target_link_libraries(little_game
PRIVATE
SDL2::SDL2 glm::glm imgui_impl_sdl2 rapidjson SDL2_image::SDL2_image
fmt::fmt spdlog::spdlog EnTT::EnTT Boost::boost)
fmt::fmt spdlog::spdlog EnTT::EnTT Boost::boost range-v3::range-v3)

if (NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_link_libraries(little_game PRIVATE Boost::stacktrace_backtrace)
endif()

set_target_properties(little_game PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS ON)
target_compile_features(little_game PUBLIC cxx_std_20)
Expand Down
1 change: 1 addition & 0 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def requirements(self):
self.requires("boost/[~1.83]")
self.requires("sdl/[~2]", override=True)
self.requires("sdl_image/[~2]")
self.requires("range-v3/[~0.12]")

if self.options.with_opengl:
self.requires("glad/[~0.1]")
Expand Down
17 changes: 12 additions & 5 deletions include/engine/sdl/Error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,22 @@
#include <SDL_error.h>
#include <fmt/core.h>

#include <stdexcept>
#include <cstring>
#include <exception>
#include <memory>

namespace engine::sdl {

class Error final : std::runtime_error {
public:
using std::runtime_error::runtime_error;
class Error final : public std::runtime_error {
private:
Error(char const *message)
: std::runtime_error(message)
{
}

[[nodiscard]] static Error current()
public:
[[nodiscard]]
static Error current()
{
return Error(SDL_GetError());
}
Expand Down
1 change: 1 addition & 0 deletions src/engine/rendering/opengl/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <engine/cache.hpp>
#include <engine/rendering/opengl/Renderer.hpp>

#include <SDL_mouse.h>
#include <glad/glad.h>
#include <glm/ext.hpp>
#include <glm/glm.hpp>
Expand Down
46 changes: 31 additions & 15 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
#include <utils/error.hpp>

#include <SDL.h>
#include <boost/core/typeinfo.hpp>
#include <boost/stacktrace.hpp>
#include <fmt/core.h>
#include <fmt/ranges.h>
#include <fmt/std.h>
#include <imgui.h>
#include <imgui_impl_sdl2.h>
#include <range/v3/view/enumerate.hpp>
#include <range/v3/view/reverse.hpp>
#include <spdlog/sinks/ringbuffer_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>
Expand All @@ -27,21 +30,6 @@ static void set_spdlog_sinks()
sinks.push_back(std::make_shared<spdlog::sinks::ringbuffer_sink_mt>(1024 * 5));
}

[[gnu::constructor]]
static void set_terminate_handler()
{
static std::terminate_handler const default_handler = std::get_terminate();

auto handler = []() {
auto const stacktrace = boost::stacktrace::stacktrace();
for (auto const &frame : stacktrace)
spdlog::critical("{}", fmt::streamed(frame)); // do not use the macro, location printed by it can be confused

default_handler();
};
std::set_terminate(+handler);
}

static std::vector<char const *> audio_drivers()
{
int const n = SDL_GetNumAudioDrivers();
Expand All @@ -64,8 +52,36 @@ static std::vector<char const *> video_drivers()
return result;
}

static void terminate_handler()
{
if (auto exception_ptr = std::current_exception()) {
try {
std::rethrow_exception(exception_ptr);
} catch (std::exception const &e) {
spdlog::critical("terminate called with an active exception");
auto const type_name = boost::core::demangled_name(typeid(e));
spdlog::critical("exception: type={:?}, what={:?}", type_name, e.what());
} catch (...) {
// TODO: find a way to get this information on Windows
auto const type_name = boost::core::demangled_name(*abi::__cxa_current_exception_type());
spdlog::critical("terminate called with an active exception");
spdlog::critical("exception: type={:?}", type_name);
}
} else {
spdlog::critical("terminate called without an active exception");
}

auto const stacktrace = boost::stacktrace::stacktrace();
spdlog::critical("stacktrace:");
for (auto const &[i, frame] : stacktrace | ranges::view::reverse | ranges::view::enumerate)
spdlog::critical(" #{:02}: {}", i, fmt::streamed(frame));
std::abort();
}

int main(int argc, char **argv)
{
std::set_terminate(+terminate_handler);

#ifdef SDL_MAIN_HANDLED
SDL_SetMainReady();
#endif
Expand Down

0 comments on commit bb29d27

Please sign in to comment.