From 940cf67e13dea9d3a7f60459a3df9e880800661d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Wed, 11 Dec 2024 17:28:29 +0200 Subject: [PATCH] [Windows] Fix loading debug symbol files over 2GB. --- .../windows/crash_handler_windows_signal.cpp | 5 +- thirdparty/README.md | 4 ++ .../libbacktrace/patches/patch_big_files.diff | 47 +++++++++++++++++++ thirdparty/libbacktrace/read.c | 22 +++++---- 4 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 thirdparty/libbacktrace/patches/patch_big_files.diff diff --git a/platform/windows/crash_handler_windows_signal.cpp b/platform/windows/crash_handler_windows_signal.cpp index ddfb9b65de00..ebc89a8181fe 100644 --- a/platform/windows/crash_handler_windows_signal.cpp +++ b/platform/windows/crash_handler_windows_signal.cpp @@ -167,7 +167,10 @@ extern void CrashHandlerException(int signal) { if (FileAccess::exists(_execpath + ".debugsymbols")) { _execpath = _execpath + ".debugsymbols"; } - data.state = backtrace_create_state(_execpath.utf8().get_data(), 0, &error_callback, reinterpret_cast(&data)); + _execpath = _execpath.replace("/", "\\"); + + CharString cs = _execpath.utf8(); // Note: should remain in scope during backtrace_simple call. + data.state = backtrace_create_state(cs.get_data(), 0, &error_callback, reinterpret_cast(&data)); if (data.state != nullptr) { data.index = 1; backtrace_simple(data.state, 1, &trace_callback, &error_callback, reinterpret_cast(&data)); diff --git a/thirdparty/README.md b/thirdparty/README.md index 669e6829fa37..258a12b840eb 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -468,6 +468,10 @@ Files extracted from upstream source: - `*.{c,h}` files for Windows platform - `LICENSE` +Important: Some files have Godot-made changes to load big debug symbol files. +They are marked with `/* GODOT start */` and `/* GODOT end */` +comments and a patch is provided in the `patches` folder. + ## libktx diff --git a/thirdparty/libbacktrace/patches/patch_big_files.diff b/thirdparty/libbacktrace/patches/patch_big_files.diff new file mode 100644 index 000000000000..6c3185c8d160 --- /dev/null +++ b/thirdparty/libbacktrace/patches/patch_big_files.diff @@ -0,0 +1,47 @@ +diff --git a/thirdparty/libbacktrace/read.c b/thirdparty/libbacktrace/read.c +index 1811c8d2e0..fda8e222d4 100644 +--- a/thirdparty/libbacktrace/read.c ++++ b/thirdparty/libbacktrace/read.c +@@ -52,14 +52,9 @@ backtrace_get_view (struct backtrace_state *state, int descriptor, + { + uint64_t got; + ssize_t r; +- +- if ((uint64_t) (size_t) size != size) +- { +- error_callback (data, "file size too large", 0); +- return 0; +- } +- +- if (lseek (descriptor, offset, SEEK_SET) < 0) ++/* GODOT start */ ++ if (_lseeki64 (descriptor, offset, SEEK_SET) < 0) ++/* GODOT end */ + { + error_callback (data, "lseek", errno); + return 0; +@@ -74,7 +69,13 @@ backtrace_get_view (struct backtrace_state *state, int descriptor, + got = 0; + while (got < size) + { +- r = read (descriptor, view->base, size - got); ++/* GODOT start */ ++ uint64_t sz = size - got; ++ if (sz > INT_MAX) { ++ sz = INT_MAX; ++ } ++ r = _read (descriptor, view->base, sz); ++/* GODOT end */ + if (r < 0) + { + error_callback (data, "read", errno); +@@ -84,6 +85,9 @@ backtrace_get_view (struct backtrace_state *state, int descriptor, + if (r == 0) + break; + got += (uint64_t) r; ++/* GODOT start */ ++ view->base += r; ++/* GODOT end */ + } + + if (got < size) diff --git a/thirdparty/libbacktrace/read.c b/thirdparty/libbacktrace/read.c index 1811c8d2e086..f5e01f01b0bf 100644 --- a/thirdparty/libbacktrace/read.c +++ b/thirdparty/libbacktrace/read.c @@ -52,14 +52,9 @@ backtrace_get_view (struct backtrace_state *state, int descriptor, { uint64_t got; ssize_t r; - - if ((uint64_t) (size_t) size != size) - { - error_callback (data, "file size too large", 0); - return 0; - } - - if (lseek (descriptor, offset, SEEK_SET) < 0) +/* GODOT start */ + if (_lseeki64 (descriptor, offset, SEEK_SET) < 0) +/* GODOT end */ { error_callback (data, "lseek", errno); return 0; @@ -74,7 +69,13 @@ backtrace_get_view (struct backtrace_state *state, int descriptor, got = 0; while (got < size) { - r = read (descriptor, view->base, size - got); +/* GODOT start */ + uint64_t sz = size - got; + if (sz > INT_MAX) { + sz = INT_MAX; + } + r = _read (descriptor, view->base, sz); +/* GODOT end */ if (r < 0) { error_callback (data, "read", errno); @@ -84,6 +85,9 @@ backtrace_get_view (struct backtrace_state *state, int descriptor, if (r == 0) break; got += (uint64_t) r; +/* GODOT start */ + view->base += r; +/* GODOT end */ } if (got < size)