载入中...
搜索中...
未找到
CrashHandler.h
浏览该文件的文档.
1#pragma once
2
3// Windows crash-backtrace support (backward-cpp / DbgHelp). Installed by both
4// the engine entry point (src/engine/main.cpp) and the unit-test runner
5// (test/main.cpp) so any unhandled exception prints a symbolized stack trace
6// instead of a bare exit code. Host-only; the backward.hpp include and the
7// EVBacktrace link target are guarded to Windows.
8
9#if defined(EVENGINE_WINDOWS) || defined(_WIN32)
10
11#ifndef NOMINMAX
12#define NOMINMAX
13#endif
14#include <windows.h>
15#include <werapi.h>
16#include <backward.hpp>
17
18#ifndef WER_FAULT_REPORTING_NO_UI
19#define WER_FAULT_REPORTING_NO_UI 0x20
20#endif
21#ifndef WER_FAULT_REPORTING_ALWAYS_SHOW_UI
22#define WER_FAULT_REPORTING_ALWAYS_SHOW_UI 0x10
23#endif
24
25#include "common/CrashLog.h"
26
27#include <cstdio>
28#include <cstdlib>
29#include <iomanip>
30#include <sstream>
31
32// backward.hpp pulls in <imagehlp.h> with its own packing; declaring the one
33// DbgHelp entry point we call directly avoids including dbghelp.h again. Match
34// imagehlp.h's dllimport linkage or MSVC warns C4273.
35extern "C" __declspec(dllimport) BOOL WINAPI SymInitialize(
36 HANDLE hProcess, PCSTR UserSearchPath, BOOL fInvadeProcess);
37
38namespace eve {
39
46inline LONG WINAPI crashHandler(EXCEPTION_POINTERS *ep) {
47 // DbgHelp must be initialized before StackWalk64, otherwise the walk
48 // produces garbage frames. Ignore the "already initialized" failure.
50 SymInitialize(GetCurrentProcess(), nullptr, TRUE);
51 std::ostringstream report;
52 report << "[crash] code=0x" << std::hex << std::setw(8) << std::setfill('0')
53 << ep->ExceptionRecord->ExceptionCode << std::dec << std::setfill(' ')
54 << " at " << ep->ExceptionRecord->ExceptionAddress << "\n";
55 try {
56 backward::StackTrace st;
57 // Walk from the handler's own frame: the exception dispatch ran on the
58 // crashing thread's stack, so the crash site is still in the chain.
59 // Walking from ep->ContextRecord produced garbage frames (0xCC) with
60 // DbgHelp StackWalk64 on this setup.
61 st.load_here(64);
62 backward::Printer p;
63 p.snippet = false;
64 p.color_mode = backward::ColorMode::never;
65 p.print(st, report);
66 } catch (...) {
67 report << "[crash] backtrace unavailable\n";
68 }
69 const std::string text = report.str();
71 std::fputs(text.c_str(), stderr);
73 std::fflush(stderr);
76 return EXCEPTION_CONTINUE_SEARCH;
77}
78
89inline void installCrashHandler() {
91 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
92 DWORD werFlags = 0;
93 if (FAILED(WerGetFlags(GetCurrentProcess(), &werFlags))) {
94 werFlags = 0;
95 }
96 (void)WerSetFlags((werFlags | WER_FAULT_REPORTING_NO_UI) &
97 ~static_cast<DWORD>(WER_FAULT_REPORTING_ALWAYS_SHOW_UI));
98#if defined(_MSC_VER)
100 _set_error_mode(_OUT_TO_STDERR);
102 _set_abort_behavior(0, _WRITE_ABORT_MSG);
103#endif
105 SetUnhandledExceptionFilter(&crashHandler);
106}
107
108} // namespace eve
109
110#endif // EVENGINE_WINDOWS || _WIN32
Persistent, thread-safe record of engine crash and problem events.
glm::vec4 p[6]
std::string text
Build metadata (engine git commit, build time, third-party version).
Definition Build.cpp:16
void recordCrashEvent(const std::string &report)
Records a crash report, safe to call from a crash/exception handler.
Definition CrashLog.cpp:78