Merge pull request #102 from chrisps/error_modules_and_threads_plus_xmacontext_workaround
Host exception improvements, bandaid over div by 0 crash
This commit is contained in:
commit
0f94eb21c2
|
@ -355,13 +355,20 @@ void XmaContext::Decode(XMA_CONTEXT_DATA* data) {
|
||||||
: nullptr;
|
: nullptr;
|
||||||
uint8_t* current_input_buffer = data->current_buffer ? in1 : in0;
|
uint8_t* current_input_buffer = data->current_buffer ? in1 : in0;
|
||||||
|
|
||||||
XELOGAPU("Processing context {} (offset {}, buffer {}, ptr {:p})", id(),
|
XELOGAPU(
|
||||||
data->input_buffer_read_offset, data->current_buffer,
|
"Processing context {} (offset {}, buffer {}, ptr {:p}, output buffer "
|
||||||
current_input_buffer);
|
"{}, output buffer count {})",
|
||||||
|
id(), data->input_buffer_read_offset, data->current_buffer,
|
||||||
|
current_input_buffer, data->output_buffer_ptr,
|
||||||
|
data->output_buffer_block_count);
|
||||||
|
|
||||||
if (!current_input_buffer) {
|
if (!current_input_buffer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!data->output_buffer_block_count) {
|
||||||
|
XELOGE("Received 0 for output_buffer_block_count!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
size_t input_buffer_0_size =
|
size_t input_buffer_0_size =
|
||||||
data->input_buffer_0_packet_count * kBytesPerPacket;
|
data->input_buffer_0_packet_count * kBytesPerPacket;
|
||||||
size_t input_buffer_1_size =
|
size_t input_buffer_1_size =
|
||||||
|
@ -492,8 +499,8 @@ void XmaContext::Decode(XMA_CONTEXT_DATA* data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame_count > 0) {
|
if (frame_count > 0) {
|
||||||
//assert_true(xma::GetPacketFrameOffset(packet) - 32 ==
|
// assert_true(xma::GetPacketFrameOffset(packet) - 32 ==
|
||||||
// split_frame_len_ - split_frame_len_partial_);
|
// split_frame_len_ - split_frame_len_partial_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (split_frame_len_partial_ > split_frame_len_) {
|
if (split_frame_len_partial_ > split_frame_len_) {
|
||||||
|
|
|
@ -80,7 +80,36 @@ static void do_ntdll_hack_this_process() {
|
||||||
(uintptr_t)GetModuleHandleA("ntdll.dll"));
|
(uintptr_t)GetModuleHandleA("ntdll.dll"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static HMODULE probe_for_module(void* addr) {
|
||||||
|
// get 65k aligned addr downwards to probe for MZ
|
||||||
|
uintptr_t base = reinterpret_cast<uintptr_t>(addr) & ~0xFFFFULL;
|
||||||
|
|
||||||
|
constexpr unsigned max_search_iters =
|
||||||
|
(64 * (1024 * 1024)) /
|
||||||
|
65536; // search down at most 64 mb (we do it in
|
||||||
|
// batches of 64k so its pretty quick). i think its reasonable to
|
||||||
|
// expect no module will be > 64mb
|
||||||
|
// break if access violation thrown, we're definitely not a PE in that case
|
||||||
|
__try {
|
||||||
|
for (unsigned i = 0; i < max_search_iters; ++i) {
|
||||||
|
if (*reinterpret_cast<unsigned short*>(base) == 'ZM') {
|
||||||
|
return reinterpret_cast<HMODULE>(base);
|
||||||
|
} else {
|
||||||
|
base -= 65536;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// end ntdll hack
|
// end ntdll hack
|
||||||
|
|
||||||
|
static constexpr auto XENIA_ERROR_LANGUAGE =
|
||||||
|
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
|
||||||
|
|
||||||
struct HostExceptionReport {
|
struct HostExceptionReport {
|
||||||
_EXCEPTION_POINTERS* const ExceptionInfo;
|
_EXCEPTION_POINTERS* const ExceptionInfo;
|
||||||
size_t Report_Scratchpos;
|
size_t Report_Scratchpos;
|
||||||
|
@ -153,13 +182,33 @@ const char* HostExceptionReport::GetFormattedAddress(uintptr_t address) {
|
||||||
char(¤t_buffer)[128] =
|
char(¤t_buffer)[128] =
|
||||||
formatted_addresses[address_format_ring_index++ % 16];
|
formatted_addresses[address_format_ring_index++ % 16];
|
||||||
|
|
||||||
if (address >= g_xenia_exe_base &&
|
/* if (address >= g_xenia_exe_base &&
|
||||||
address - g_xenia_exe_base < g_xenia_exe_size) {
|
address - g_xenia_exe_base < g_xenia_exe_size) {
|
||||||
uintptr_t offset = address - g_xenia_exe_base;
|
uintptr_t offset = address - g_xenia_exe_base;
|
||||||
|
|
||||||
sprintf_s(current_buffer, "xenia_canary.exe+%llX", offset);
|
sprintf_s(current_buffer, "xenia_canary.exe+%llX", offset);
|
||||||
} else {
|
} else */
|
||||||
sprintf_s(current_buffer, "0x%llX", address);
|
{
|
||||||
|
HMODULE hmod_for = probe_for_module((void*)address);
|
||||||
|
|
||||||
|
if (hmod_for) {
|
||||||
|
// get the module filename, then chomp off all but the actual file name
|
||||||
|
// (full path is obtained)
|
||||||
|
char tmp_module_name[MAX_PATH + 1];
|
||||||
|
GetModuleFileNameA(hmod_for, tmp_module_name, sizeof(tmp_module_name));
|
||||||
|
|
||||||
|
size_t search_back = strlen(tmp_module_name);
|
||||||
|
// hunt backwards for the last sep
|
||||||
|
while (tmp_module_name[--search_back] != '\\')
|
||||||
|
;
|
||||||
|
|
||||||
|
// MessageBoxA(nullptr, tmp_module_name, "ffds", MB_OK);
|
||||||
|
sprintf_s(current_buffer, "%s+%llX", tmp_module_name + search_back + 1,
|
||||||
|
address - reinterpret_cast<uintptr_t>(hmod_for));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
sprintf_s(current_buffer, "0x%llX", address);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return current_buffer;
|
return current_buffer;
|
||||||
}
|
}
|
||||||
|
@ -168,9 +217,8 @@ static char* Ntstatus_msg(NTSTATUS status) {
|
||||||
char* statusmsg = nullptr;
|
char* statusmsg = nullptr;
|
||||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
|
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
GetModuleHandleA("ntdll.dll"), status,
|
GetModuleHandleA("ntdll.dll"), status, XENIA_ERROR_LANGUAGE,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&statusmsg,
|
(LPSTR)&statusmsg, 0, NULL);
|
||||||
0, NULL);
|
|
||||||
return statusmsg;
|
return statusmsg;
|
||||||
}
|
}
|
||||||
static bool exception_pointers_handler(HostExceptionReport* report) {
|
static bool exception_pointers_handler(HostExceptionReport* report) {
|
||||||
|
@ -206,9 +254,8 @@ static bool exception_win32_error_handle(HostExceptionReport* report) {
|
||||||
char* statusmsg = nullptr;
|
char* statusmsg = nullptr;
|
||||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
NULL, report->last_win32_error,
|
nullptr, report->last_win32_error, XENIA_ERROR_LANGUAGE,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&statusmsg,
|
(LPSTR)&statusmsg, 0, nullptr);
|
||||||
0, NULL);
|
|
||||||
sprintf_s(win32_error_buf, "Last Win32 Error: 0x%X (%s)\n",
|
sprintf_s(win32_error_buf, "Last Win32 Error: 0x%X (%s)\n",
|
||||||
report->last_win32_error,
|
report->last_win32_error,
|
||||||
HostExceptionReport::ChompNewlines(statusmsg));
|
HostExceptionReport::ChompNewlines(statusmsg));
|
||||||
|
@ -240,9 +287,35 @@ static bool exception_cerror_handle(HostExceptionReport* report) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool thread_name_handle(HostExceptionReport* report) {
|
||||||
|
// ll GetThreadDescription(HANDLE hThread, PWSTR *ppszThreadDescription)
|
||||||
|
|
||||||
|
FARPROC description_getter =
|
||||||
|
GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetThreadDescription");
|
||||||
|
|
||||||
|
if (!description_getter) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PWSTR descr = nullptr;
|
||||||
|
|
||||||
|
reinterpret_cast<HRESULT (*)(HANDLE, PWSTR*)>(description_getter)(
|
||||||
|
GetCurrentThread(), &descr);
|
||||||
|
|
||||||
|
if (!descr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char result_buffer[512];
|
||||||
|
|
||||||
|
sprintf_s(result_buffer, "Faulting thread name: %ws\n", descr);
|
||||||
|
|
||||||
|
report->AddString(result_buffer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
static ExceptionInfoCategoryHandler host_exception_category_handlers[] = {
|
static ExceptionInfoCategoryHandler host_exception_category_handlers[] = {
|
||||||
exception_pointers_handler, exception_win32_error_handle,
|
exception_pointers_handler, exception_win32_error_handle,
|
||||||
exception_ntstatus_error_handle, exception_cerror_handle};
|
exception_ntstatus_error_handle, exception_cerror_handle,
|
||||||
|
thread_name_handle};
|
||||||
|
|
||||||
LONG _UnhandledExceptionFilter(_EXCEPTION_POINTERS* ExceptionInfo) {
|
LONG _UnhandledExceptionFilter(_EXCEPTION_POINTERS* ExceptionInfo) {
|
||||||
HostExceptionReport report{ExceptionInfo};
|
HostExceptionReport report{ExceptionInfo};
|
||||||
|
|
Loading…
Reference in New Issue