game/debugger: handle uncaught loader thread exceptions and better handle that situation on the windows debugger (#2075)

This commit is contained in:
Tyler Wilding
2023-01-01 12:31:12 -05:00
committed by GitHub
parent 0cddf6b6a5
commit 73d38bd9ff
5 changed files with 77 additions and 79 deletions
+8 -6
View File
@@ -471,12 +471,14 @@ bool check_stopped(const ThreadID& tid, SignalInfo* out) {
{
auto exc = debugEvent.u.Exception.ExceptionRecord.ExceptionCode;
if (is_other) {
if (exc == EXCEPTION_BREAKPOINT) {
out->kind = SignalInfo::BREAK;
} else {
// ignore exceptions outside goal thread
ignore_debug_event();
}
ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId,
DBG_EXCEPTION_NOT_HANDLED);
// if (exc == EXCEPTION_BREAKPOINT) {
// out->kind = SignalInfo::BREAK;
// } else {
// // ignore exceptions outside goal thread
// ignore_debug_event();
// }
} else {
switch (exc) {
case EXCEPTION_BREAKPOINT:
+5 -5
View File
@@ -143,18 +143,18 @@ void ReplWrapper::init_default_settings() {
// - https://github.com/ClickHouse/ClickHouse/blob/master/base/base/ReplxxLineReader.cpp#L366
repl.set_word_break_characters(" \t");
// Setup default keybinds
// (test-play) : Ctrl-P
// (test-play) : Ctrl-T
repl.bind_key(Replxx::KEY::control('T'), commit_text_action("(test-play)"));
// (e) : Ctrl-Q
repl.bind_key(Replxx::KEY::control('Q'), commit_text_action("(e)"));
// (lt) : Ctrl-G
// (lt) : Ctrl-L
repl.bind_key(Replxx::KEY::control('L'), commit_text_action("(lt)"));
/// (:stop) : Ctrl-H
/// (:stop) : Ctrl-W
repl.bind_key(Replxx::KEY::control('W'), commit_text_action("(:stop)"));
// (dbgc) : Ctrl-F
// (dbgc) : Ctrl-G
repl.bind_key(Replxx::KEY::control('G'), commit_text_action("(dbgc)"));
// (:di) : Ctrl-B
repl.bind_key(Replxx::KEY::control('B'), commit_text_action("(:di)"));
// (mi) : Ctrl-M
// (mi) : Ctrl-N
repl.bind_key(Replxx::KEY::control('N'), commit_text_action("(mi)"));
}
+1 -1
View File
@@ -461,7 +461,7 @@
115, // goto L55
121,
131
],
],
"(anon-function 4 gun-states)": [94, 96, 98],
"target-board-handler": [
13, 14, 18
+4 -12
View File
@@ -5377,9 +5377,7 @@
[11, "v1", "drawable-tree-instance-shrub"],
[38, "v1", "drawable-tree-instance-tie"]
],
"dma-add-process-drawable-hud": [
[11, "a0", "foreground-work"]
],
"dma-add-process-drawable-hud": [[11, "a0", "foreground-work"]],
"find-instance-by-index": [
[26, "t1", "drawable-tree-instance-shrub"],
[40, "t1", "drawable-tree-instance-tie"]
@@ -5395,15 +5393,9 @@
[[44, 64], "s1", "drawable-inline-array-instance-tie"],
[[331, 450], "s5", "prototype-bucket-tie"]
],
"set-shadow-by-name": [
[7, "v1", "process-drawable"]
],
"get-shadow-by-name": [
[7, "v1", "process-drawable"]
],
"(anon-function 2 memory-usage)": [
[211, "v1", "collide-shape-moving"]
],
"set-shadow-by-name": [[7, "v1", "process-drawable"]],
"get-shadow-by-name": [[7, "v1", "process-drawable"]],
"(anon-function 2 memory-usage)": [[211, "v1", "collide-shape-moving"]],
"(method 9 screen-filter)": [
[[25, 31], "a0", "dma-packet"],
[[34, 40], "a0", "gs-gif-tag"],
+59 -55
View File
@@ -101,66 +101,70 @@ std::vector<LevelData*> Loader::get_in_use_levels() {
* This is used for file I/O and unpacking.
*/
void Loader::loader_thread() {
while (!m_want_shutdown) {
std::unique_lock<std::mutex> lk(m_loader_mutex);
try {
while (!m_want_shutdown) {
std::unique_lock<std::mutex> lk(m_loader_mutex);
// this will keep us asleep until we've got a level to load.
m_loader_cv.wait(lk, [&] { return !m_level_to_load.empty() || m_want_shutdown; });
if (m_want_shutdown) {
return;
}
std::string lev = m_level_to_load;
// don't hold the lock while reading the file.
lk.unlock();
// simulate slower hard drive (so that the loader thread can lose to the game loads)
// std::this_thread::sleep_for(std::chrono::milliseconds(1500));
// load the fr3 file
Timer disk_timer;
auto data =
file_util::read_binary_file(m_base_path / fmt::format("{}.fr3", uppercase_string(lev)));
double disk_load_time = disk_timer.getSeconds();
// the FR3 files are compressed
Timer decomp_timer;
auto decomp_data = compression::decompress_zstd(data.data(), data.size());
double decomp_time = decomp_timer.getSeconds();
// Read back into the tfrag3::Level structure
Timer import_timer;
auto result = std::make_unique<tfrag3::Level>();
Serializer ser(decomp_data.data(), decomp_data.size());
result->serialize(ser);
double import_time = import_timer.getSeconds();
// and finally "unpack", which creates the vertex data we'll upload to the GPU
Timer unpack_timer;
for (auto& tie_tree : result->tie_trees) {
for (auto& tree : tie_tree) {
tree.unpack();
// this will keep us asleep until we've got a level to load.
m_loader_cv.wait(lk, [&] { return !m_level_to_load.empty() || m_want_shutdown; });
if (m_want_shutdown) {
return;
}
}
for (auto& t_tree : result->tfrag_trees) {
for (auto& tree : t_tree) {
tree.unpack();
std::string lev = m_level_to_load;
// don't hold the lock while reading the file.
lk.unlock();
// simulate slower hard drive (so that the loader thread can lose to the game loads)
// std::this_thread::sleep_for(std::chrono::milliseconds(1500));
// load the fr3 file
Timer disk_timer;
auto data =
file_util::read_binary_file(m_base_path / fmt::format("{}.fr3", uppercase_string(lev)));
double disk_load_time = disk_timer.getSeconds();
// the FR3 files are compressed
Timer decomp_timer;
auto decomp_data = compression::decompress_zstd(data.data(), data.size());
double decomp_time = decomp_timer.getSeconds();
// Read back into the tfrag3::Level structure
Timer import_timer;
auto result = std::make_unique<tfrag3::Level>();
Serializer ser(decomp_data.data(), decomp_data.size());
result->serialize(ser);
double import_time = import_timer.getSeconds();
// and finally "unpack", which creates the vertex data we'll upload to the GPU
Timer unpack_timer;
for (auto& tie_tree : result->tie_trees) {
for (auto& tree : tie_tree) {
tree.unpack();
}
}
for (auto& t_tree : result->tfrag_trees) {
for (auto& tree : t_tree) {
tree.unpack();
}
}
}
for (auto& shrub_tree : result->shrub_trees) {
shrub_tree.unpack();
}
fmt::print(
"------------> Load from file: {:.3f}s, import {:.3f}s, decomp {:.3f}s unpack {:.3f}s\n",
disk_load_time, import_time, decomp_time, unpack_timer.getSeconds());
for (auto& shrub_tree : result->shrub_trees) {
shrub_tree.unpack();
}
fmt::print(
"------------> Load from file: {:.3f}s, import {:.3f}s, decomp {:.3f}s unpack {:.3f}s\n",
disk_load_time, import_time, decomp_time, unpack_timer.getSeconds());
// grab the lock again
lk.lock();
// move this level to "initializing" state.
m_initializing_tfrag3_levels[lev] = std::make_unique<LevelData>(); // reset load state
m_initializing_tfrag3_levels[lev]->level = std::move(result);
m_level_to_load = "";
m_file_load_done_cv.notify_all();
// grab the lock again
lk.lock();
// move this level to "initializing" state.
m_initializing_tfrag3_levels[lev] = std::make_unique<LevelData>(); // reset load state
m_initializing_tfrag3_levels[lev]->level = std::move(result);
m_level_to_load = "";
m_file_load_done_cv.notify_all();
}
} catch (std::exception& e) {
ASSERT_MSG(false, fmt::format("Exception {} encountered in loader_thread", e.what()));
}
}