2323
2424#pragma once
2525
26+ #include < array>
2627#include < sstream>
2728#include < stdexcept>
2829#include < string>
2930
3031#include < absl/base/optimization.h>
32+ #include < absl/debugging/stacktrace.h>
33+ #include < absl/debugging/symbolize.h>
3134#include < absl/strings/str_cat.h>
3235
3336#include < geode/basic/opengeode_basic_export.hpp>
@@ -49,13 +52,44 @@ namespace geode
4952 */
5053 class OpenGeodeException : public std ::runtime_error
5154 {
55+ static constexpr int MAX_STACK_DEPTH = 10 ;
56+ static constexpr int NB_SKIPPED_STACKS = 1 ;
57+ static constexpr int SYMBOL_SIZE = 1024 ;
58+
5259 public:
5360 template < typename ... Args >
5461 explicit OpenGeodeException ( const Args&... message )
55- : std::runtime_error{ absl::StrCat ( message... ) }
62+ : std::runtime_error{ absl::StrCat ( message... ) },
63+ stack_size_{ absl::GetStackTrace (
64+ stack_.data (), MAX_STACK_DEPTH, NB_SKIPPED_STACKS ) }
65+ {
66+ }
67+
68+ ~OpenGeodeException () noexcept override = default ;
69+
70+ std::string stack_trace () const
5671 {
72+ std::string stack_string;
73+ for ( auto frame = 0 ; frame < stack_size_; ++frame )
74+ {
75+ absl::StrAppend ( &stack_string, " " , frame, " : " );
76+ if ( std::array< char , SYMBOL_SIZE > symbol; absl::Symbolize (
77+ stack_[frame], symbol.data (), sizeof ( symbol ) ) )
78+ {
79+ absl::StrAppend ( &stack_string, symbol.data () );
80+ }
81+ else
82+ {
83+ absl::StrAppend ( &stack_string, " Unknown" );
84+ }
85+ absl::StrAppend ( &stack_string, " \n " );
86+ }
87+ return stack_string;
5788 }
58- virtual ~OpenGeodeException () noexcept {}
89+
90+ private:
91+ std::array< void *, MAX_STACK_DEPTH > stack_;
92+ int stack_size_;
5993 };
6094
6195 void opengeode_basic_api geode_assertion_failed ( std::string_view condition,
0 commit comments