4#include <Tempest/Except>
5#include <Tempest/Platform>
13#if defined(__cpp_lib_stacktrace)
17#if defined(__LINUX__) || defined(__APPLE__)
23#include <dbg/frames.hpp>
24#include <dbg/symbols.hpp>
31static LONG WINAPI exceptionHandler(PEXCEPTION_POINTERS) {
32 SetUnhandledExceptionFilter(
nullptr);
34 return EXCEPTION_EXECUTE_HANDLER;
39 std::signal(sig, SIG_DFL);
40 const char* sname =
nullptr;
51 std::snprintf(buf,16,
"%d",sig);
61 char msg[128] =
"std::terminate";
62 std::exception_ptr p = std::current_exception();
63 std::string extGpuLog;
66 std::rethrow_exception(p);
69 std::signal(SIGABRT, SIG_DFL);
72 catch (Tempest::DeviceLostException& e) {
73 std::snprintf(msg,
sizeof(msg),
"DeviceLostException(%s)",e.what());
76 catch (Tempest::BadTextureCastException& e) {
77 std::snprintf(msg,
sizeof(msg),
"BadTextureCastException(%s)",e.what());
79 catch (std::system_error& e) {
80 std::snprintf(msg,
sizeof(msg),
"std::system_error(%s)",e.what());
82 catch (std::runtime_error& e) {
83 std::snprintf(msg,
sizeof(msg),
"std::runtime_error(%s)",e.what());
85 catch (std::logic_error& e) {
86 std::snprintf(msg,
sizeof(msg),
"std::logic_error(%s)",e.what());
88 catch (std::bad_alloc& e) {
89 std::snprintf(msg,
sizeof(msg),
"std::bad_alloc(%s)",e.what());
91 catch (std::exception& e) {
92 std::snprintf(msg,
sizeof(msg),
"std::exception(%s)",e.what());
98 std::signal(SIGABRT, SIG_DFL);
104 SetUnhandledExceptionFilter(exceptionHandler);
121#if !defined(__cpp_lib_stacktrace) && defined(__WINDOWS__)
123 dbg::call_stack<64> traceback;
128 std::cout.setf(std::ios::unitbuf);
129 std::cout << std::endl <<
"---crashlog(" << sig <<
")---" << std::endl;
130 writeSysInfo(std::cout);
131 tracebackGpu(std::cout, extGpuLog);
132#if defined(__cpp_lib_stacktrace)
133 tracebackStd(std::cout);
134#elif defined(__WINDOWS__)
135 traceback.collect(0);
136 traceback.log(db, std::cout);
137#elif defined(__LINUX__) || defined(__APPLE__)
138 tracebackLinux(std::cout);
140 std::cout << std::endl;
142 std::ofstream fout(
"crash.log");
143 fout.setf(std::ios::unitbuf);
144 fout <<
"---crashlog(" << sig <<
")---" << std::endl;
146 tracebackGpu(std::cout, extGpuLog);
147#if defined(__cpp_lib_stacktrace)
149#elif defined(__WINDOWS__)
150 traceback.log(db, fout);
151#elif defined(__LINUX__) || defined(__APPLE__)
152 tracebackLinux(fout);
157void CrashLog::tracebackStd(std::ostream &out) {
158#if defined(__cpp_lib_stacktrace)
159 auto trace = std::stacktrace::current();
161 uint32_t frameId = 0;
162 for (
auto& i : trace) {
163 out <<
" #" << frameId <<
"\t" << i.description() <<
":" << i.source_line() <<
" in " << i.source_file() << std::endl;
169void CrashLog::tracebackLinux(std::ostream &out) {
170#if defined(__LINUX__) || defined(__APPLE__)
172 void *callstack[64] = {};
173 char **symbols =
nullptr;
175 framesNum = backtrace(callstack, 64);
176 symbols = backtrace_symbols(callstack, framesNum);
177 if(symbols !=
nullptr) {
181 const char* frame =
"";
182 for(
int i = skip; i < framesNum && loop; i++) {
183 if(dladdr(callstack[i], &info) && info.dli_sname) {
185 if(info.dli_sname[0] ==
'_')
186 frame = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status);
187 frame = status == 0 ? frame : info.dli_sname == 0 ? symbols[i] : info.dli_sname;
189 if(!strcmp(
"main", frame)) {
193 if(strcmp(frame, symbols[i]))
194 out <<
"#" << i-skip+1 <<
": " << frame <<
" - " << symbols[i] << std::endl;
196 out <<
"#" << i-skip+1 <<
": " << frame << std::endl;
203void CrashLog::tracebackGpu(std::ostream& out,
const char* extGpuLog) {
204 if(extGpuLog==
nullptr || extGpuLog[0]==
'\0')
207 out <<
"---gpulog begin---" << std::endl;
208 out << extGpuLog << std::endl;
209 out <<
"---gpulog end ---" << std::endl;
213void CrashLog::writeSysInfo(std::ostream &fout) {
214 fout <<
"GPU: " <<
gpuName << std::endl;
static void setGpu(std::string_view name)
static void dumpStack(const char *sig, const char *extGpuLog)
static void terminateHandler()
static void signalHandler(int sig)