mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
Fix bad exit condition when looping exception records
This commit is contained in:
parent
9c2d2b7c1d
commit
e09c43b8de
1 changed files with 43 additions and 35 deletions
|
|
@ -119,7 +119,7 @@ std::wstring describe_module(const std::filesystem::path& path) {
|
||||||
return std::format(L"<error: GetFileVersionInfoSizeW#2 returned {}>", GetLastError());
|
return std::format(L"<error: GetFileVersionInfoSizeW#2 returned {}>", GetLastError());
|
||||||
|
|
||||||
UINT size = 0;
|
UINT size = 0;
|
||||||
|
|
||||||
std::wstring version = L"v?.?.?.?";
|
std::wstring version = L"v?.?.?.?";
|
||||||
if (LPVOID lpBuffer; VerQueryValueW(block.data(), L"\\", &lpBuffer, &size)) {
|
if (LPVOID lpBuffer; VerQueryValueW(block.data(), L"\\", &lpBuffer, &size)) {
|
||||||
const auto& v = *static_cast<const VS_FIXEDFILEINFO*>(lpBuffer);
|
const auto& v = *static_cast<const VS_FIXEDFILEINFO*>(lpBuffer);
|
||||||
|
|
@ -176,7 +176,7 @@ const std::map<HMODULE, size_t>& get_remote_modules() {
|
||||||
std::vector<HMODULE> buf(8192);
|
std::vector<HMODULE> buf(8192);
|
||||||
for (size_t i = 0; i < 64; i++) {
|
for (size_t i = 0; i < 64; i++) {
|
||||||
if (DWORD needed; !EnumProcessModules(g_hProcess, &buf[0], static_cast<DWORD>(std::span(buf).size_bytes()), &needed)) {
|
if (DWORD needed; !EnumProcessModules(g_hProcess, &buf[0], static_cast<DWORD>(std::span(buf).size_bytes()), &needed)) {
|
||||||
std::cerr << std::format("EnumProcessModules error: 0x{:x}", GetLastError()) << std::endl;
|
std::cerr << std::format("EnumProcessModules error: 0x{:x}", GetLastError()) << std::endl;
|
||||||
break;
|
break;
|
||||||
} else if (needed > std::span(buf).size_bytes()) {
|
} else if (needed > std::span(buf).size_bytes()) {
|
||||||
buf.resize(needed / sizeof(HMODULE) + 16);
|
buf.resize(needed / sizeof(HMODULE) + 16);
|
||||||
|
|
@ -201,7 +201,7 @@ const std::map<HMODULE, size_t>& get_remote_modules() {
|
||||||
|
|
||||||
data[hModule] = nth64.OptionalHeader.SizeOfImage;
|
data[hModule] = nth64.OptionalHeader.SizeOfImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
|
@ -292,35 +292,43 @@ std::wstring to_address_string(const DWORD64 address, const bool try_ptrderef =
|
||||||
|
|
||||||
void print_exception_info(HANDLE hThread, const EXCEPTION_POINTERS& ex, const CONTEXT& ctx, std::wostringstream& log) {
|
void print_exception_info(HANDLE hThread, const EXCEPTION_POINTERS& ex, const CONTEXT& ctx, std::wostringstream& log) {
|
||||||
std::vector<EXCEPTION_RECORD> exRecs;
|
std::vector<EXCEPTION_RECORD> exRecs;
|
||||||
if (ex.ExceptionRecord) {
|
if (ex.ExceptionRecord)
|
||||||
|
{
|
||||||
size_t rec_index = 0;
|
size_t rec_index = 0;
|
||||||
size_t read;
|
size_t read;
|
||||||
exRecs.emplace_back();
|
|
||||||
for (auto pRemoteExRec = ex.ExceptionRecord;
|
for (auto pRemoteExRec = ex.ExceptionRecord;
|
||||||
pRemoteExRec
|
pRemoteExRec && rec_index < 64;
|
||||||
&& rec_index < 64
|
rec_index++)
|
||||||
&& ReadProcessMemory(g_hProcess, pRemoteExRec, &exRecs.back(), sizeof exRecs.back(), &read)
|
{
|
||||||
&& read >= offsetof(EXCEPTION_RECORD, ExceptionInformation)
|
exRecs.emplace_back();
|
||||||
&& read >= static_cast<size_t>(reinterpret_cast<const char*>(&exRecs.back().ExceptionInformation[exRecs.back().NumberParameters]) - reinterpret_cast<const char*>(&exRecs.back()));
|
|
||||||
rec_index++) {
|
if (!ReadProcessMemory(g_hProcess, pRemoteExRec, &exRecs.back(), sizeof exRecs.back(), &read)
|
||||||
|
|| read < offsetof(EXCEPTION_RECORD, ExceptionInformation)
|
||||||
|
|| read < static_cast<size_t>(reinterpret_cast<const char*>(&exRecs.back().ExceptionInformation[exRecs.
|
||||||
|
back().NumberParameters]) - reinterpret_cast<const char*>(&exRecs.back())))
|
||||||
|
{
|
||||||
|
exRecs.pop_back();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
log << std::format(L"\nException Info #{}\n", rec_index);
|
log << std::format(L"\nException Info #{}\n", rec_index);
|
||||||
log << std::format(L"Address: {:X}\n", exRecs.back().ExceptionCode);
|
log << std::format(L"Address: {:X}\n", exRecs.back().ExceptionCode);
|
||||||
log << std::format(L"Flags: {:X}\n", exRecs.back().ExceptionFlags);
|
log << std::format(L"Flags: {:X}\n", exRecs.back().ExceptionFlags);
|
||||||
log << std::format(L"Address: {:X}\n", reinterpret_cast<size_t>(exRecs.back().ExceptionAddress));
|
log << std::format(L"Address: {:X}\n", reinterpret_cast<size_t>(exRecs.back().ExceptionAddress));
|
||||||
if (!exRecs.back().NumberParameters)
|
if (exRecs.back().NumberParameters)
|
||||||
continue;
|
{
|
||||||
log << L"Parameters: ";
|
log << L"Parameters: ";
|
||||||
for (DWORD i = 0; i < exRecs.back().NumberParameters; ++i) {
|
for (DWORD i = 0; i < exRecs.back().NumberParameters; ++i)
|
||||||
if (i != 0)
|
{
|
||||||
log << L", ";
|
if (i != 0)
|
||||||
log << std::format(L"{:X}", exRecs.back().ExceptionInformation[i]);
|
log << L", ";
|
||||||
|
log << std::format(L"{:X}", exRecs.back().ExceptionInformation[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pRemoteExRec = exRecs.back().ExceptionRecord;
|
pRemoteExRec = exRecs.back().ExceptionRecord;
|
||||||
exRecs.emplace_back();
|
|
||||||
}
|
}
|
||||||
exRecs.pop_back();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log << L"\nCall Stack\n{";
|
log << L"\nCall Stack\n{";
|
||||||
|
|
@ -410,7 +418,7 @@ void print_exception_info_extended(const EXCEPTION_POINTERS& ex, const CONTEXT&
|
||||||
|
|
||||||
std::wstring escape_shell_arg(const std::wstring& arg) {
|
std::wstring escape_shell_arg(const std::wstring& arg) {
|
||||||
// https://docs.microsoft.com/en-us/archive/blogs/twistylittlepassagesallalike/everyone-quotes-command-line-arguments-the-wrong-way
|
// https://docs.microsoft.com/en-us/archive/blogs/twistylittlepassagesallalike/everyone-quotes-command-line-arguments-the-wrong-way
|
||||||
|
|
||||||
std::wstring res;
|
std::wstring res;
|
||||||
if (!arg.empty() && arg.find_first_of(L" \t\n\v\"") == std::wstring::npos) {
|
if (!arg.empty() && arg.find_first_of(L" \t\n\v\"") == std::wstring::npos) {
|
||||||
res.append(arg);
|
res.append(arg);
|
||||||
|
|
@ -504,7 +512,7 @@ void export_tspack(HWND hWndParent, const std::filesystem::path& logDir, const s
|
||||||
filePath.emplace(pFilePath);
|
filePath.emplace(pFilePath);
|
||||||
|
|
||||||
std::fstream fileStream(*filePath, std::ios::binary | std::ios::in | std::ios::out | std::ios::trunc);
|
std::fstream fileStream(*filePath, std::ios::binary | std::ios::in | std::ios::out | std::ios::trunc);
|
||||||
|
|
||||||
mz_zip_archive zipa{};
|
mz_zip_archive zipa{};
|
||||||
zipa.m_pIO_opaque = &fileStream;
|
zipa.m_pIO_opaque = &fileStream;
|
||||||
zipa.m_pRead = [](void* pOpaque, mz_uint64 file_ofs, void* pBuf, size_t n) -> size_t {
|
zipa.m_pRead = [](void* pOpaque, mz_uint64 file_ofs, void* pBuf, size_t n) -> size_t {
|
||||||
|
|
@ -566,7 +574,7 @@ void export_tspack(HWND hWndParent, const std::filesystem::path& logDir, const s
|
||||||
const auto hLogFile = CreateFileW(logFilePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr);
|
const auto hLogFile = CreateFileW(logFilePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr);
|
||||||
if (hLogFile == INVALID_HANDLE_VALUE)
|
if (hLogFile == INVALID_HANDLE_VALUE)
|
||||||
throw_last_error(std::format("indiv. log file: CreateFileW({})", ws_to_u8(logFilePath.wstring())));
|
throw_last_error(std::format("indiv. log file: CreateFileW({})", ws_to_u8(logFilePath.wstring())));
|
||||||
|
|
||||||
std::unique_ptr<void, decltype(&CloseHandle)> hLogFileClose(hLogFile, &CloseHandle);
|
std::unique_ptr<void, decltype(&CloseHandle)> hLogFileClose(hLogFile, &CloseHandle);
|
||||||
|
|
||||||
LARGE_INTEGER size, baseOffset{};
|
LARGE_INTEGER size, baseOffset{};
|
||||||
|
|
@ -695,7 +703,7 @@ int main() {
|
||||||
|
|
||||||
// IFileSaveDialog only works on STA
|
// IFileSaveDialog only works on STA
|
||||||
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
|
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
|
||||||
|
|
||||||
std::vector<std::wstring> args;
|
std::vector<std::wstring> args;
|
||||||
if (int argc = 0; const auto argv = CommandLineToArgvW(GetCommandLineW(), &argc)) {
|
if (int argc = 0; const auto argv = CommandLineToArgvW(GetCommandLineW(), &argc)) {
|
||||||
for (auto i = 0; i < argc; i++)
|
for (auto i = 0; i < argc; i++)
|
||||||
|
|
@ -823,14 +831,14 @@ int main() {
|
||||||
hr = pOleWindow->GetWindow(&hwndProgressDialog);
|
hr = pOleWindow->GetWindow(&hwndProgressDialog);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
SetWindowPos(hwndProgressDialog, HWND_TOPMOST, 0, 0, 0, 0,
|
SetWindowPos(hwndProgressDialog, HWND_TOPMOST, 0, 0, 0, 0,
|
||||||
SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
|
SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
|
||||||
SetForegroundWindow(hwndProgressDialog);
|
SetForegroundWindow(hwndProgressDialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
pOleWindow->Release();
|
pOleWindow->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cerr << "Failed to create progress window" << std::endl;
|
std::cerr << "Failed to create progress window" << std::endl;
|
||||||
|
|
@ -852,14 +860,14 @@ int main() {
|
||||||
|
|
||||||
https://github.com/sumatrapdfreader/sumatrapdf/blob/master/src/utils/DbgHelpDyn.cpp
|
https://github.com/sumatrapdfreader/sumatrapdf/blob/master/src/utils/DbgHelpDyn.cpp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (g_bSymbolsAvailable) {
|
if (g_bSymbolsAvailable) {
|
||||||
SymRefreshModuleList(g_hProcess);
|
SymRefreshModuleList(g_hProcess);
|
||||||
}
|
}
|
||||||
else if(!assetDir.empty())
|
else if(!assetDir.empty())
|
||||||
{
|
{
|
||||||
auto symbol_search_path = std::format(L".;{}", (assetDir / "UIRes" / "pdb").wstring());
|
auto symbol_search_path = std::format(L".;{}", (assetDir / "UIRes" / "pdb").wstring());
|
||||||
|
|
||||||
g_bSymbolsAvailable = SymInitializeW(g_hProcess, symbol_search_path.c_str(), true);
|
g_bSymbolsAvailable = SymInitializeW(g_hProcess, symbol_search_path.c_str(), true);
|
||||||
std::wcout << std::format(L"Init symbols with PDB at {}", symbol_search_path) << std::endl;
|
std::wcout << std::format(L"Init symbols with PDB at {}", symbol_search_path) << std::endl;
|
||||||
|
|
||||||
|
|
@ -870,12 +878,12 @@ int main() {
|
||||||
g_bSymbolsAvailable = SymInitializeW(g_hProcess, nullptr, true);
|
g_bSymbolsAvailable = SymInitializeW(g_hProcess, nullptr, true);
|
||||||
std::cout << "Init symbols without PDB" << std::endl;
|
std::cout << "Init symbols without PDB" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_bSymbolsAvailable) {
|
if (!g_bSymbolsAvailable) {
|
||||||
std::wcerr << std::format(L"SymInitialize error: 0x{:x}", GetLastError()) << std::endl;
|
std::wcerr << std::format(L"SymInitialize error: 0x{:x}", GetLastError()) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pProgressDialog)
|
if (pProgressDialog)
|
||||||
pProgressDialog->SetLine(3, L"Reading troubleshooting data", FALSE, NULL);
|
pProgressDialog->SetLine(3, L"Reading troubleshooting data", FALSE, NULL);
|
||||||
|
|
||||||
std::wstring stackTrace(exinfo.dwStackTraceLength, L'\0');
|
std::wstring stackTrace(exinfo.dwStackTraceLength, L'\0');
|
||||||
|
|
@ -936,7 +944,7 @@ int main() {
|
||||||
|
|
||||||
if (shutup)
|
if (shutup)
|
||||||
log << L"======= Crash handler was globally muted(shutdown?) =======" << std::endl;
|
log << L"======= Crash handler was globally muted(shutdown?) =======" << std::endl;
|
||||||
|
|
||||||
if (dumpPath.empty())
|
if (dumpPath.empty())
|
||||||
log << L"Dump skipped" << std::endl;
|
log << L"Dump skipped" << std::endl;
|
||||||
else if (dumpError.empty())
|
else if (dumpError.empty())
|
||||||
|
|
@ -1003,7 +1011,7 @@ int main() {
|
||||||
R"aa(<a href="help">Help</a> | <a href="logdir">Open log directory</a> | <a href="logfile">Open log file</a>)aa"
|
R"aa(<a href="help">Help</a> | <a href="logdir">Open log directory</a> | <a href="logfile">Open log file</a>)aa"
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Can't do this, xiv stops pumping messages here
|
// Can't do this, xiv stops pumping messages here
|
||||||
//config.hwndParent = FindWindowA("FFXIVGAME", NULL);
|
//config.hwndParent = FindWindowA("FFXIVGAME", NULL);
|
||||||
|
|
||||||
|
|
@ -1056,13 +1064,13 @@ int main() {
|
||||||
return (*reinterpret_cast<decltype(callback)*>(dwRefData))(hwnd, uNotification, wParam, lParam);
|
return (*reinterpret_cast<decltype(callback)*>(dwRefData))(hwnd, uNotification, wParam, lParam);
|
||||||
};
|
};
|
||||||
config.lpCallbackData = reinterpret_cast<LONG_PTR>(&callback);
|
config.lpCallbackData = reinterpret_cast<LONG_PTR>(&callback);
|
||||||
|
|
||||||
if (pProgressDialog) {
|
if (pProgressDialog) {
|
||||||
pProgressDialog->StopProgressDialog();
|
pProgressDialog->StopProgressDialog();
|
||||||
pProgressDialog->Release();
|
pProgressDialog->Release();
|
||||||
pProgressDialog = NULL;
|
pProgressDialog = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto kill_game = [&] { TerminateProcess(g_hProcess, exinfo.ExceptionRecord.ExceptionCode); };
|
const auto kill_game = [&] { TerminateProcess(g_hProcess, exinfo.ExceptionRecord.ExceptionCode); };
|
||||||
|
|
||||||
if (shutup) {
|
if (shutup) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue