[XboxKrnl] Don't crash the host on guest trap
This commit is contained in:
@@ -9,10 +9,15 @@
|
|||||||
|
|
||||||
#include "xenia/base/debugging.h"
|
#include "xenia/base/debugging.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
|
#include "xenia/emulator.h"
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
#include "xenia/kernel/util/shim_utils.h"
|
#include "xenia/kernel/util/shim_utils.h"
|
||||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
|
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
|
||||||
#include "xenia/kernel/xthread.h"
|
#include "xenia/kernel/xthread.h"
|
||||||
|
#include "xenia/ui/imgui_dialog.h"
|
||||||
|
#include "xenia/ui/imgui_drawer.h"
|
||||||
|
#include "xenia/ui/window.h"
|
||||||
|
#include "xenia/ui/windowed_app_context.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
@@ -147,13 +152,39 @@ DECLARE_XBOXKRNL_EXPORT2(RtlRaiseException, kDebug, kStub, kImportant);
|
|||||||
|
|
||||||
void KeBugCheckEx_entry(dword_t code, dword_t param1, dword_t param2,
|
void KeBugCheckEx_entry(dword_t code, dword_t param1, dword_t param2,
|
||||||
dword_t param3, dword_t param4) {
|
dword_t param3, dword_t param4) {
|
||||||
XELOGD("*** STOP: 0x{:08X} (0x{:08X}, 0x{:08X}, 0x{:08X}, 0x{:08X})",
|
auto msg =
|
||||||
static_cast<uint32_t>(code), static_cast<uint32_t>(param1),
|
fmt::format("*** STOP: 0x{:08X} (0x{:08X}, 0x{:08X}, 0x{:08X}, 0x{:08X})",
|
||||||
static_cast<uint32_t>(param2), static_cast<uint32_t>(param3),
|
static_cast<uint32_t>(code), static_cast<uint32_t>(param1),
|
||||||
static_cast<uint32_t>(param4));
|
static_cast<uint32_t>(param2), static_cast<uint32_t>(param3),
|
||||||
|
static_cast<uint32_t>(param4));
|
||||||
|
XELOGE("{}", msg);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
xe::debugging::Break();
|
|
||||||
assert_always();
|
if (xe::debugging::IsDebuggerAttached()) {
|
||||||
|
xe::debugging::Break();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show crash dialog and suspend the guest thread instead of killing the
|
||||||
|
// host process.
|
||||||
|
auto current_thread = kernel::XThread::GetCurrentThread();
|
||||||
|
const auto* emulator = kernel_state()->emulator();
|
||||||
|
auto* display_window = emulator->display_window();
|
||||||
|
auto* imgui_drawer = emulator->imgui_drawer();
|
||||||
|
if (display_window && imgui_drawer) {
|
||||||
|
auto dlg_msg = fmt::format(
|
||||||
|
"The guest kernel has crashed (KeBugCheck).\n\n{}\n\n"
|
||||||
|
"The faulting thread has been suspended.",
|
||||||
|
msg);
|
||||||
|
display_window->app_context().CallInUIThreadSynchronous(
|
||||||
|
[imgui_drawer, &dlg_msg]() {
|
||||||
|
xe::ui::ImGuiDialog::ShowMessageBox(imgui_drawer,
|
||||||
|
"Guest Kernel Crash", dlg_msg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_thread) {
|
||||||
|
current_thread->Suspend(nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DECLARE_XBOXKRNL_EXPORT2(KeBugCheckEx, kDebug, kStub, kImportant);
|
DECLARE_XBOXKRNL_EXPORT2(KeBugCheckEx, kDebug, kStub, kImportant);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user