From 95bc34e41c5ae00a563d8f6398d24629bd41818e Mon Sep 17 00:00:00 2001
From: Death Killer <884052+deathkiller@users.noreply.github.com>
Date: Sat, 24 Feb 2024 11:27:25 +0100
Subject: [PATCH] Refactoring
---
Sources/Jazz2.vcxproj | 1 +
Sources/Jazz2.vcxproj.filters | 6 +
Sources/Main.cpp | 5 +-
Sources/backward/backward.h | 131 ++++++++++--------
Sources/nCine/Application.cpp | 24 +++-
Sources/nCine/Application.h | 1 +
.../Backends/Android/AndroidApplication.cpp | 5 +-
Sources/nCine/MainApplication.cpp | 5 +-
8 files changed, 106 insertions(+), 72 deletions(-)
diff --git a/Sources/Jazz2.vcxproj b/Sources/Jazz2.vcxproj
index f7f6d8ec..d8a77059 100644
--- a/Sources/Jazz2.vcxproj
+++ b/Sources/Jazz2.vcxproj
@@ -230,6 +230,7 @@
+
diff --git a/Sources/Jazz2.vcxproj.filters b/Sources/Jazz2.vcxproj.filters
index 10c15e7c..7ee9bd1b 100644
--- a/Sources/Jazz2.vcxproj.filters
+++ b/Sources/Jazz2.vcxproj.filters
@@ -223,6 +223,9 @@
{a72d645b-36b7-485e-b3f6-5ec77cbd0ee2}
+
+ {78d8395e-85f4-4b64-a565-54001b8dde6e}
+
@@ -1470,6 +1473,9 @@
Header Files\Shared\Containers
+
+ Header Files\backward
+
diff --git a/Sources/Main.cpp b/Sources/Main.cpp
index 021bd327..646d598a 100644
--- a/Sources/Main.cpp
+++ b/Sources/Main.cpp
@@ -163,7 +163,10 @@ void GameEventHandler::OnPreInit(AppConfiguration& config)
{
ZoneScopedC(0x888888);
- PreferencesCache::Initialize(config);
+ // TODO: Only to simulate crash
+ AppConfiguration& config2 = *(AppConfiguration*)123;
+
+ PreferencesCache::Initialize(config2);
config.windowTitle = NCINE_APP_NAME;
if (PreferencesCache::MaxFps == PreferencesCache::UseVsync) {
diff --git a/Sources/backward/backward.h b/Sources/backward/backward.h
index 38af6067..82289611 100644
--- a/Sources/backward/backward.h
+++ b/Sources/backward/backward.h
@@ -180,9 +180,11 @@
#if !defined(_GNU_SOURCE)
# define _GNU_SOURCE
# include
+# include
# undef _GNU_SOURCE
#else
# include
+# include
#endif
#if BACKWARD_HAS_BFD == 1
@@ -297,11 +299,8 @@ typedef SSIZE_T ssize_t;
#endif
#include
-
-#if !defined(DEATH_TARGET_32BIT)
-# include
-# include
-#endif
+#include
+#include
#include
#include
@@ -316,6 +315,7 @@ typedef SSIZE_T ssize_t;
// Some versions of imagehlp.dll lack the proper packing directives themselves
// so we need to do it.
#pragma pack(push, before_imagehlp, 8)
+#define _IMAGEHLP64
#include
#pragma pack(pop, before_imagehlp)
@@ -703,6 +703,11 @@ namespace backward {
}
protected:
+ size_t _thread_id;
+ size_t _skip;
+ void* _context;
+ void* _error_addr;
+
void load_thread_info() {
#if defined(BACKWARD_SYSTEM_LINUX)
# if !defined(DEATH_TARGET_ANDROID)
@@ -741,12 +746,6 @@ namespace backward {
size_t skip_n_firsts() const {
return _skip;
}
-
- private:
- size_t _thread_id;
- size_t _skip;
- void* _context;
- void* _error_addr;
};
class StackTraceImplHolder : public StackTraceImplBase {
@@ -1112,6 +1111,8 @@ namespace backward {
thd_ = ::GetCurrentThread();
}
+ _thread_id = (size_t)::GetThreadId(thd_);
+
HANDLE process = ::GetCurrentProcess();
STACKFRAME64 s;
@@ -3558,22 +3559,12 @@ namespace backward {
}
DWORD offset = 0;
-#if defined(DEATH_TARGET_32BIT)
- // 32-bit library doesn't have SymGetLineFromAddrW() function
- IMAGEHLP_LINE line = { sizeof(IMAGEHLP_LINE) };
- if (::SymGetLineFromAddr(process, (ULONG64)t.addr, &offset, &line)) {
- t.source.filename = line.FileName;
- t.source.line = line.LineNumber;
- t.source.col = offset;
- }
-#else
IMAGEHLP_LINEW64 lineW = { sizeof(IMAGEHLP_LINEW64) };
- if (::SymGetLineFromAddrW(process, (ULONG64)t.addr, &offset, &lineW)) {
+ if (::SymGetLineFromAddrW64(process, (ULONG64)t.addr, &offset, &lineW)) {
t.source.filename = Death::Utf8::FromUtf16(lineW.FileName);
t.source.line = lineW.LineNumber;
t.source.col = offset;
}
-#endif
t.source.function = name;
t.object_function = name;
@@ -3597,7 +3588,7 @@ namespace backward {
class SourceFile {
public:
- typedef std::vector > lines_t;
+ typedef std::vector> lines_t;
SourceFile() {}
SourceFile(const std::string& path) {
@@ -3712,8 +3703,7 @@ namespace backward {
}
private:
- details::handle>
- _file;
+ details::handle> _file;
static std::vector get_paths_from_env_variable_impl() {
std::vector paths;
@@ -3828,7 +3818,6 @@ namespace backward {
cfile_streambuf& operator=(const cfile_streambuf&) = delete;
FILE* sink;
- std::vector buffer;
};
# if defined(BACKWARD_SYSTEM_LINUX) || defined(BACKWARD_SYSTEM_WINDOWS)
@@ -3901,38 +3890,38 @@ namespace backward {
inliner_context_size(5), trace_context_size(7) {}
template
- FILE* print(ST& st, FILE* fp = stderr) {
+ FILE* print(ST& st, FILE* fp = stderr, int signal = 0) {
cfile_streambuf obuf(fp);
std::ostream os(&obuf);
Colorize colorize(os);
colorize.activate(color_mode);
- print_stacktrace(st, os, colorize);
+ print_stacktrace(st, os, signal, colorize);
return fp;
}
template
- std::ostream& print(ST& st, std::ostream& os) {
+ std::ostream& print(ST& st, std::ostream& os, int signal = 0) {
Colorize colorize(os);
colorize.activate(color_mode);
- print_stacktrace(st, os, colorize);
+ print_stacktrace(st, os, signal, colorize);
return os;
}
template
- FILE* print(IT begin, IT end, FILE* fp = stderr, size_t thread_id = 0) {
+ FILE* print(IT begin, IT end, FILE* fp = stderr, size_t thread_id = 0, int signal = 0) {
cfile_streambuf obuf(fp);
std::ostream os(&obuf);
Colorize colorize(os);
colorize.activate(color_mode);
- print_stacktrace(begin, end, os, thread_id, colorize);
+ print_stacktrace(begin, end, os, thread_id, signal, colorize);
return fp;
}
template
- std::ostream& print(IT begin, IT end, std::ostream& os, size_t thread_id = 0) {
+ std::ostream& print(IT begin, IT end, std::ostream& os, size_t thread_id = 0, int signal = 0) {
Colorize colorize(os);
colorize.activate(color_mode);
- print_stacktrace(begin, end, os, thread_id, colorize);
+ print_stacktrace(begin, end, os, thread_id, signal, colorize);
return os;
}
@@ -3945,8 +3934,8 @@ namespace backward {
SnippetFactory _snippets;
template
- void print_stacktrace(ST& st, std::ostream& os, Colorize& colorize) {
- print_header(os, st.thread_id(), colorize);
+ void print_stacktrace(ST& st, std::ostream& os, int signal, Colorize& colorize) {
+ print_header(os, st.thread_id(), signal, colorize);
_resolver.load_stacktrace(st);
bool failed = false;
for (size_t trace_idx = 0; trace_idx < st.size(); ++trace_idx) {
@@ -3967,17 +3956,26 @@ namespace backward {
}
template
- void print_stacktrace(IT begin, IT end, std::ostream& os, size_t thread_id, Colorize& colorize) {
- print_header(os, thread_id, colorize);
+ void print_stacktrace(IT begin, IT end, std::ostream& os, size_t thread_id, int signal, Colorize& colorize) {
+ print_header(os, thread_id, signal, colorize);
for (; begin != end; ++begin) {
print_trace(os, *begin, colorize);
}
}
- void print_header(std::ostream& os, size_t thread_id, Colorize& colorize) {
+ void print_header(std::ostream& os, size_t thread_id, int signal, Colorize& colorize) {
colorize.set_color(Color::bold);
os << "The application exited unexpectedly";
colorize.set_color(Color::reset);
+ if (signal != 0) {
+ os << " due to signal " << signal;
+# if defined(BACKWARD_SYSTEM_LINUX)
+ const char* signalName = sigabbrev_np(signal);
+ if (signalName != nullptr) {
+ os << " (SIG" << signalName << ")";
+ }
+# endif
+ }
os << " with following stack trace";
if (thread_id != 0) {
os << " in thread " << thread_id;
@@ -4088,7 +4086,7 @@ namespace backward {
SIGEMT, // emulation instruction executed
# endif
};
- return std::vector(posix_signals, posix_signals + sizeof posix_signals / sizeof posix_signals[0]);
+ return std::vector(posix_signals, posix_signals + sizeof(posix_signals) / sizeof(posix_signals[0]));
}
SignalHandling(const std::vector& posix_signals = make_default_signals())
@@ -4142,14 +4140,19 @@ namespace backward {
return data;
}
- static void handleSignal(int, siginfo_t* info, void* _ctx) {
+ static FILE*& destination() {
+ static FILE* data = nullptr;
+ return data;
+ }
+
+ static void handleSignal(int signo, siginfo_t* info, void* _ctx) {
ucontext_t* uctx = static_cast(_ctx);
StackTrace st;
void* error_addr = nullptr;
-# if defined(REG_RIP) // x86_64
+# if defined(REG_RIP) // 64-bit x86
error_addr = reinterpret_cast(uctx->uc_mcontext.gregs[REG_RIP]);
-# elif defined(REG_EIP) // x86_32
+# elif defined(REG_EIP) // 32-bit x86
error_addr = reinterpret_cast(uctx->uc_mcontext.gregs[REG_EIP]);
# elif defined(__arm__)
error_addr = reinterpret_cast(uctx->uc_mcontext.arm_pc);
@@ -4184,14 +4187,16 @@ namespace backward {
Printer printer;
printer.color_mode = color_mode();
printer.address = true;
- printer.print(st, stderr);
-# if (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) || \
- (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L)
- psiginfo(info, nullptr);
-# else
- (void)info;
-# endif
+ FILE* dest = destination();
+ printer.print(st, dest != nullptr ? dest : stderr, info->si_signo);
+
+//# if (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) || \
+// (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L)
+// psiginfo(info, nullptr);
+//# else
+// (void)info;
+//# endif
}
private:
@@ -4230,7 +4235,7 @@ namespace backward {
{
std::unique_lock lk(mtx());
- cv().wait(lk, [] { return crashed() != crash_status::running; });
+ cv().wait(lk, []() { return crashed() != crash_status::running; });
}
if (crashed() == crash_status::crashed) {
handle_stacktrace(skip_recs());
@@ -4244,10 +4249,10 @@ namespace backward {
::SetUnhandledExceptionFilter(crash_handler);
signal(SIGABRT, signal_handler);
-#if !defined(_Build_By_LTL)
- // This function is not supported on VC-LTL 4.1.3
- _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
-#endif
+//#if !defined(_Build_By_LTL)
+// // This function is not supported on VC-LTL 4.1.3
+// _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
+//#endif
std::set_terminate(&terminator);
# if !defined(BACKWARD_ATLEAST_CXX17)
@@ -4256,6 +4261,7 @@ namespace backward {
_set_purecall_handler(&terminator);
_set_invalid_parameter_handler(&invalid_parameter_handler);
}
+
bool loaded() const {
return true;
}
@@ -4276,6 +4282,11 @@ namespace backward {
return data;
}
+ static FILE*& destination() {
+ static FILE* data = nullptr;
+ return data;
+ }
+
private:
static CONTEXT* ctx() {
static CONTEXT data;
@@ -4369,7 +4380,7 @@ namespace backward {
{
std::unique_lock lk(mtx());
- cv().wait(lk, [] { return crashed() != crash_status::crashed; });
+ cv().wait(lk, []() { return crashed() != crash_status::crashed; });
}
}
@@ -4389,7 +4400,13 @@ namespace backward {
st.skip_n_firsts(skip_frames);
printer.address = true;
- printer.print(st, std::cerr);
+
+ FILE* dest = destination();
+ if (dest != nullptr) {
+ printer.print(st, dest);
+ } else {
+ printer.print(st, std::cerr);
+ }
}
};
diff --git a/Sources/nCine/Application.cpp b/Sources/nCine/Application.cpp
index 6c5781cd..f3cf143b 100644
--- a/Sources/nCine/Application.cpp
+++ b/Sources/nCine/Application.cpp
@@ -452,6 +452,24 @@ namespace nCine
}
}
+ void Application::preInitCommon(std::unique_ptr appEventHandler)
+ {
+#if defined(WITH_BACKWARD)
+# if defined(DEATH_TARGET_ANDROID)
+ // Try to save crash info to log file
+ sh.destination() = __logFile->GetHandle();
+# elif defined(DEATH_TARGET_APPLE) || defined(DEATH_TARGET_EMSCRIPTEN) || defined(DEATH_TARGET_UNIX) || defined(DEATH_TARGET_WINDOWS)
+ if (__hasVirtualTerminal) {
+ sh.color_mode() = backward::ColorMode::always;
+ }
+# endif
+#endif
+
+ appEventHandler_ = std::move(appEventHandler);
+ appEventHandler_->OnPreInit(appCfg_);
+ LOGI("IAppEventHandler::OnPreInit() invoked");
+ }
+
void Application::initCommon()
{
TracyGpuContext;
@@ -459,12 +477,6 @@ namespace nCine
// This timestamp is needed to initialize random number generator
profileStartTime_ = TimeStamp::now();
-#if defined(WITH_BACKWARD) && (defined(DEATH_TARGET_APPLE) || defined(DEATH_TARGET_EMSCRIPTEN) || defined(DEATH_TARGET_UNIX) || defined(DEATH_TARGET_WINDOWS))
- if (__hasVirtualTerminal) {
- sh.color_mode() = backward::ColorMode::always;
- }
-#endif
-
LOGI(NCINE_APP_NAME " v" NCINE_VERSION " initializing...");
#if defined(WITH_TRACY)
TracyAppInfo(NCINE_APP, sizeof(NCINE_APP) - 1);
diff --git a/Sources/nCine/Application.h b/Sources/nCine/Application.h
index 5eb6b2e8..f12cc908 100644
--- a/Sources/nCine/Application.h
+++ b/Sources/nCine/Application.h
@@ -196,6 +196,7 @@ namespace nCine
Application();
~Application();
+ void preInitCommon(std::unique_ptr appEventHandler);
/// Must be called before giving control to the application
void initCommon();
/// A single step of the game loop made to render a frame
diff --git a/Sources/nCine/Backends/Android/AndroidApplication.cpp b/Sources/nCine/Backends/Android/AndroidApplication.cpp
index 11e40278..b96d0627 100644
--- a/Sources/nCine/Backends/Android/AndroidApplication.cpp
+++ b/Sources/nCine/Backends/Android/AndroidApplication.cpp
@@ -247,10 +247,7 @@ namespace nCine
LOGI("Running on %s %s (%s)", AndroidJniClass_Version::deviceBrand().data(), AndroidJniClass_Version::deviceModel().data(), AndroidJniClass_Version::deviceManufacturer().data());
#endif
- appEventHandler_ = createAppEventHandler_();
- // Only `OnPreInit()` can modify the application configuration
- appEventHandler_->OnPreInit(appCfg_);
- LOGI("IAppEventHandler::OnPreInit() invoked");
+ preInitCommon(createAppEventHandler());
}
void AndroidApplication::init()
diff --git a/Sources/nCine/MainApplication.cpp b/Sources/nCine/MainApplication.cpp
index bd5c0c86..500c664e 100644
--- a/Sources/nCine/MainApplication.cpp
+++ b/Sources/nCine/MainApplication.cpp
@@ -307,8 +307,6 @@ namespace nCine
# endif
#endif
- appEventHandler_ = createAppEventHandler();
-
// Only `OnPreInit()` can modify the application configuration
if (argc > 1) {
#if defined(DEATH_TARGET_WINDOWS)
@@ -324,8 +322,7 @@ namespace nCine
#endif
}
- appEventHandler_->OnPreInit(appCfg_);
- LOGI("IAppEventHandler::OnPreInit() invoked");
+ preInitCommon(createAppEventHandler());
// Graphics device should always be created before the input manager!
IGfxDevice::GLContextInfo glContextInfo(appCfg_);