Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc: More DuckStation backports #11204

Merged
merged 5 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/scripts/linux/flatpak/modules/20-sdl2.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"sources": [
{
"type": "archive",
"url": "https://libsdl.org/release/SDL2-2.30.2.tar.gz",
"sha256": "891d66ac8cae51361d3229e3336ebec1c407a8a2a063b61df14f5fdf3ab5ac31"
"url": "https://libsdl.org/release/SDL2-2.30.3.tar.gz",
"sha256": "820440072f8f5b50188c1dae104f2ad25984de268785be40c41a099a510f0aec"
}
],
"cleanup": [
Expand Down
2 changes: 1 addition & 1 deletion cmake/SearchForStuff.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ find_package(ZLIB REQUIRED) # v1.3, but Mac uses the SDK version.
find_package(Zstd 1.5.5 REQUIRED)
find_package(LZ4 REQUIRED)
find_package(WebP REQUIRED) # v1.3.2, spews an error on Linux because no pkg-config.
find_package(SDL2 2.30.2 REQUIRED)
find_package(SDL2 2.30.3 REQUIRED)
find_package(Freetype 2.11.1 REQUIRED)

if(USE_VULKAN)
Expand Down
81 changes: 18 additions & 63 deletions common/CrashHandler.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: LGPL-3.0+

#include "Pcsx2Defs.h"
#include "CrashHandler.h"
#include "DynamicLibrary.h"
#include "FileSystem.h"
#include "StringUtil.h"
#include <cinttypes>
Expand Down Expand Up @@ -75,8 +76,7 @@ static bool WriteMinidump(HMODULE hDbgHelp, HANDLE hFile, HANDLE hProcess, DWORD
}

static std::wstring s_write_directory;
static HMODULE s_dbghelp_module = nullptr;
static PVOID s_veh_handle = nullptr;
static DynamicLibrary s_dbghelp_module;
static bool s_in_crash_handler = false;

static void GenerateCrashFilename(wchar_t* buf, size_t len, const wchar_t* prefix, const wchar_t* extension)
Expand Down Expand Up @@ -114,7 +114,7 @@ static void WriteMinidumpAndCallstack(PEXCEPTION_POINTERS exi)
MiniDumpWithThreadInfo | MiniDumpWithIndirectlyReferencedMemory);
const HANDLE hMinidumpFile = CreateFileW(filename, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr);
if (hMinidumpFile == INVALID_HANDLE_VALUE ||
!WriteMinidump(s_dbghelp_module, hMinidumpFile, GetCurrentProcess(), GetCurrentProcessId(),
!WriteMinidump(static_cast<HMODULE>(s_dbghelp_module.GetHandle()), hMinidumpFile, GetCurrentProcess(), GetCurrentProcessId(),
GetCurrentThreadId(), exi, minidump_type))
{
static const char error_message[] = "Failed to write minidump file.\n";
Expand All @@ -136,50 +136,30 @@ static void WriteMinidumpAndCallstack(PEXCEPTION_POINTERS exi)

static LONG NTAPI ExceptionHandler(PEXCEPTION_POINTERS exi)
{
if (s_in_crash_handler)
return EXCEPTION_CONTINUE_SEARCH;
// if the debugger is attached, or we're recursively crashing, let it take care of it.
if (!s_in_crash_handler)
WriteMinidumpAndCallstack(exi);

switch (exi->ExceptionRecord->ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
case EXCEPTION_BREAKPOINT:
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
case EXCEPTION_INT_DIVIDE_BY_ZERO:
case EXCEPTION_INT_OVERFLOW:
case EXCEPTION_PRIV_INSTRUCTION:
case EXCEPTION_ILLEGAL_INSTRUCTION:
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
case EXCEPTION_STACK_OVERFLOW:
case EXCEPTION_GUARD_PAGE:
break;

default:
return EXCEPTION_CONTINUE_SEARCH;
}

// if the debugger is attached, let it take care of it.
if (IsDebuggerPresent())
return EXCEPTION_CONTINUE_SEARCH;

WriteMinidumpAndCallstack(exi);
// returning EXCEPTION_CONTINUE_SEARCH makes sense, except for the fact that it seems to leave zombie processes
// around. instead, force ourselves to terminate.
TerminateProcess(GetCurrentProcess(), 0xFEFEFEFEu);
return EXCEPTION_CONTINUE_SEARCH;
}

bool CrashHandler::Install()
{
// load dbghelp at install/startup, that way we're not LoadLibrary()'ing after a crash
// .. because that probably wouldn't go down well.
s_dbghelp_module = StackWalker::LoadDbgHelpLibrary();
HMODULE mod = StackWalker::LoadDbgHelpLibrary();
if (mod)
s_dbghelp_module.Adopt(mod);

s_veh_handle = AddVectoredExceptionHandler(0, ExceptionHandler);
return (s_veh_handle != nullptr);
SetUnhandledExceptionFilter(ExceptionHandler);
return true;
}

void CrashHandler::SetWriteDirectory(const std::string_view& dump_directory)
void CrashHandler::SetWriteDirectory(std::string_view dump_directory)
{
if (!s_veh_handle)
return;

s_write_directory = FileSystem::GetWin32Path(dump_directory);
}

Expand All @@ -188,21 +168,6 @@ void CrashHandler::WriteDumpForCaller()
WriteMinidumpAndCallstack(nullptr);
}

void CrashHandler::Uninstall()
{
if (s_veh_handle)
{
RemoveVectoredExceptionHandler(s_veh_handle);
s_veh_handle = nullptr;
}

if (s_dbghelp_module)
{
FreeLibrary(s_dbghelp_module);
s_dbghelp_module = nullptr;
}
}

#elif defined(HAS_LIBBACKTRACE)

#include "FileSystem.h"
Expand Down Expand Up @@ -382,37 +347,27 @@ bool CrashHandler::Install()
return true;
}

void CrashHandler::SetWriteDirectory(const std::string_view& dump_directory)
void CrashHandler::SetWriteDirectory(std::string_view dump_directory)
{
}

void CrashHandler::WriteDumpForCaller()
{
}

void CrashHandler::Uninstall()
{
// We can't really unchain the signal handlers... so, YOLO.
}


#else

bool CrashHandler::Install()
{
return false;
}

void CrashHandler::SetWriteDirectory(const std::string_view& dump_directory)
void CrashHandler::SetWriteDirectory(std::string_view dump_directory)
{
}

void CrashHandler::WriteDumpForCaller()
{
}

void CrashHandler::Uninstall()
{
}

#endif
5 changes: 2 additions & 3 deletions common/CrashHandler.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: LGPL-3.0+

#include <string_view>

namespace CrashHandler
{
bool Install();
void SetWriteDirectory(const std::string_view& dump_directory);
void SetWriteDirectory(std::string_view dump_directory);
void WriteDumpForCaller();
void Uninstall();
} // namespace CrashHandler
9 changes: 9 additions & 0 deletions common/DynamicLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ bool DynamicLibrary::Open(const char* filename, Error* error)
#endif
}

void DynamicLibrary::Adopt(void* handle)
{
pxAssertRel(handle, "Handle is valid");

Close();

m_handle = handle;
}

void DynamicLibrary::Close()
{
if (!IsOpen())
Expand Down
6 changes: 6 additions & 0 deletions common/DynamicLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class DynamicLibrary final
/// Returns true if the library was loaded and can be used.
bool Open(const char* filename, Error* error);

/// Adopts, or takes ownership of an existing opened library.
void Adopt(void* handle);

/// Unloads the library, any function pointers from this library are no longer valid.
void Close();

Expand All @@ -61,6 +64,9 @@ class DynamicLibrary final
return *ptr != nullptr;
}

/// Returns the opaque OS-specific handle.
void* GetHandle() const { return m_handle; }

/// Move assignment, transfer ownership.
DynamicLibrary& operator=(DynamicLibrary&& move);

Expand Down
7 changes: 4 additions & 3 deletions common/Error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,13 @@ void Error::SetHResult(std::string_view prefix, long err)
static_cast<DWORD>(std::size(buf)), nullptr);
if (r > 0)
{
m_description =
fmt::format("{}HRESULT {:08X}: {}", prefix, err, StringUtil::WideStringToUTF8String(std::wstring_view(buf, r)));
m_description = fmt::format("{}HRESULT {:08X}: {}", prefix, static_cast<unsigned>(err),
StringUtil::WideStringToUTF8String(std::wstring_view(buf, r)));
}
else
{
m_description = fmt::format("{}HRESULT {:08X}: <Could not resolve system error ID>", prefix, err);
m_description = fmt::format("{}HRESULT {:08X}: <Could not resolve system error ID>", prefix,
static_cast<unsigned>(err));
}
}

Expand Down
24 changes: 9 additions & 15 deletions common/HostSys.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: LGPL-3.0+

#pragma once
Expand All @@ -10,6 +10,8 @@
#include <memory>
#include <string>

class Error;

// --------------------------------------------------------------------------------------
// PageProtectionMode
// --------------------------------------------------------------------------------------
Expand Down Expand Up @@ -83,14 +85,6 @@ static __fi PageProtectionMode PageAccess_Any()
return PageProtectionMode().All();
}

struct PageFaultInfo
{
uptr pc;
uptr addr;
};

using PageFaultHandler = bool(*)(const PageFaultInfo& info);

// --------------------------------------------------------------------------------------
// HostSys
// --------------------------------------------------------------------------------------
Expand All @@ -111,12 +105,6 @@ namespace HostSys
extern void* MapSharedMemory(void* handle, size_t offset, void* baseaddr, size_t size, const PageProtectionMode& mode);
extern void UnmapSharedMemory(void* baseaddr, size_t size);

/// Installs the specified page fault handler. Only one handler can be active at once.
bool InstallPageFaultHandler(PageFaultHandler handler);

/// Removes the page fault handler. handler is only specified to check against the active callback.
void RemovePageFaultHandler(PageFaultHandler handler);

/// JIT write protect for Apple Silicon. Needs to be called prior to writing to any RWX pages.
#if !defined(__APPLE__) || !defined(_M_ARM64)
// clang-format -off
Expand All @@ -137,6 +125,12 @@ namespace HostSys
#endif
}

namespace PageFaultHandler
{
bool HandlePageFault(uptr pc, uptr addr, bool is_write);
bool Install(Error* error);
} // namespace PageFaultHandler

class SharedMemoryMappingArea
{
public:
Expand Down
Loading