From ea00f1bb82cd4975a1cf8a6ab8161c903f1c9ac5 Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Sun, 10 Apr 2022 13:19:50 +0530 Subject: [PATCH] Flush emulation logs after exceptions A lot of logs are incomplete due to being unable to flush inside the signal handler, now we flush after any exceptions so that there is a guarantee of any exceptions being logged as this is crucial for proper debugging. --- app/src/main/cpp/skyline/kernel/types/KThread.cpp | 2 ++ app/src/main/cpp/skyline/nce.cpp | 7 +++++++ app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp | 2 ++ app/src/main/cpp/skyline/soc/host1x/command_fifo.cpp | 2 ++ 4 files changed, 13 insertions(+) diff --git a/app/src/main/cpp/skyline/kernel/types/KThread.cpp b/app/src/main/cpp/skyline/kernel/types/KThread.cpp index d25fc171..86cf1aad 100644 --- a/app/src/main/cpp/skyline/kernel/types/KThread.cpp +++ b/app/src/main/cpp/skyline/kernel/types/KThread.cpp @@ -177,6 +177,7 @@ namespace skyline::kernel::type { __builtin_unreachable(); } catch (const std::exception &e) { Logger::Error(e.what()); + Logger::EmulationContext.Flush(); if (id) { signal::BlockSignal({SIGINT}); state.process->Kill(false); @@ -186,6 +187,7 @@ namespace skyline::kernel::type { } catch (const signal::SignalException &e) { if (e.signal != SIGINT) { Logger::Error(e.what()); + Logger::EmulationContext.Flush(); if (id) { signal::BlockSignal({SIGINT}); state.process->Kill(false); diff --git a/app/src/main/cpp/skyline/nce.cpp b/app/src/main/cpp/skyline/nce.cpp index 8ee56652..ad3872e3 100644 --- a/app/src/main/cpp/skyline/nce.cpp +++ b/app/src/main/cpp/skyline/nce.cpp @@ -41,10 +41,14 @@ namespace skyline::nce { } catch (const signal::SignalException &e) { if (e.signal != SIGINT) { Logger::ErrorNoPrefix("{} (SVC: {})\nStack Trace:{}", e.what(), svc.name, state.loader->GetStackTrace(e.frames)); + Logger::EmulationContext.Flush(); + if (state.thread->id) { signal::BlockSignal({SIGINT}); state.process->Kill(false); } + } else { + Logger::EmulationContext.Flush(); } abi::__cxa_end_catch(); // We call this prior to the longjmp to cause the exception object to be destroyed std::longjmp(state.thread->originalCtx, true); @@ -60,6 +64,8 @@ namespace skyline::nce { else Logger::ErrorNoPrefix("{} (SVC: 0x{:X})\nStack Trace:{}", e.what(), svcId, state.loader->GetStackTrace()); + Logger::EmulationContext.Flush(); + if (state.thread->id) { signal::BlockSignal({SIGINT}); state.process->Kill(false); @@ -94,6 +100,7 @@ namespace skyline::nce { cpuContext += fmt::format("\n X{:<2}: 0x{:<16X} X{:<2}: 0x{:X}", index, mctx.regs[index], index + 1, mctx.regs[index + 1]); Logger::Error("Thread #{} has crashed due to signal: {}\nStack Trace:{}\nCPU Context:{}", state.thread->id, strsignal(signal), trace, cpuContext); + Logger::EmulationContext.Flush(); if (state.thread->id) { signal::BlockSignal({SIGINT}); diff --git a/app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp b/app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp index 77695743..07bdc876 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp +++ b/app/src/main/cpp/skyline/soc/gm20b/gpfifo.cpp @@ -346,11 +346,13 @@ namespace skyline::soc::gm20b { } catch (const signal::SignalException &e) { if (e.signal != SIGINT) { Logger::Error("{}\nStack Trace:{}", e.what(), state.loader->GetStackTrace(e.frames)); + Logger::EmulationContext.Flush(); signal::BlockSignal({SIGINT}); state.process->Kill(false); } } catch (const std::exception &e) { Logger::Error(e.what()); + Logger::EmulationContext.Flush(); signal::BlockSignal({SIGINT}); state.process->Kill(false); } diff --git a/app/src/main/cpp/skyline/soc/host1x/command_fifo.cpp b/app/src/main/cpp/skyline/soc/host1x/command_fifo.cpp index 6d31bf51..92eccb31 100644 --- a/app/src/main/cpp/skyline/soc/host1x/command_fifo.cpp +++ b/app/src/main/cpp/skyline/soc/host1x/command_fifo.cpp @@ -126,11 +126,13 @@ namespace skyline::soc::host1x { } catch (const signal::SignalException &e) { if (e.signal != SIGINT) { Logger::Error("{}\nStack Trace:{}", e.what(), state.loader->GetStackTrace(e.frames)); + Logger::EmulationContext.Flush(); signal::BlockSignal({SIGINT}); state.process->Kill(false); } } catch (const std::exception &e) { Logger::Error(e.what()); + Logger::EmulationContext.Flush(); signal::BlockSignal({SIGINT}); state.process->Kill(false); }