aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorp0358 <p0358@users.noreply.github.com>2024-09-08 00:48:12 +0200
committerGitHub <noreply@github.com>2024-09-08 00:48:12 +0200
commit8824340644b0da9d30c35232789acdea93db2569 (patch)
tree72eecb9c5b80b28b9f00955e8cc1160284ff76a0
parent8c546ed68c83b42cdff32d9b848b25ec2cba9c18 (diff)
downloadNorthstarLauncher-1.28.1-rc1.tar.gz
NorthstarLauncher-1.28.1-rc1.zip
Set thread names for game threads (#666)v1.28.1-rc1v1.28.1v1.28.0-rc5v1.28.0-rc4v1.28.0
Adds nice thread names that can be visible in crash dumps, non-attachable debuggers and generally in all places where old method of throwing exceptions to attached debugger on game start wouldn't work
-rw-r--r--primedev/client/audio.cpp40
-rw-r--r--primedev/core/tier0.cpp29
2 files changed, 69 insertions, 0 deletions
diff --git a/primedev/client/audio.cpp b/primedev/client/audio.cpp
index 15f5c2ae..4a759cda 100644
--- a/primedev/client/audio.cpp
+++ b/primedev/client/audio.cpp
@@ -509,6 +509,40 @@ static void __fastcall h_MilesLog(int level, const char* string)
spdlog::info("[MSS] {} - {}", level, string);
}
+static void(__fastcall* o_pSub_18003EBD0)(DWORD dwThreadID, const char* threadName) = nullptr;
+static void __fastcall h_Sub_18003EBD0(DWORD dwThreadID, const char* threadName)
+{
+ HANDLE hThread = OpenThread(THREAD_SET_LIMITED_INFORMATION, FALSE, dwThreadID);
+
+ if (hThread != NULL)
+ {
+ // TODO: This "method" of "charset conversion" from string to wstring is abhorrent. Change it to a proper one
+ // as soon as Northstar has some helper function to do proper charset conversions.
+ auto tmp = std::string(threadName);
+ HRESULT WINAPI _SetThreadDescription(HANDLE hThread, PCWSTR lpThreadDescription);
+ _SetThreadDescription(hThread, std::wstring(tmp.begin(), tmp.end()).c_str());
+
+ CloseHandle(hThread);
+ }
+
+ o_pSub_18003EBD0(dwThreadID, threadName);
+}
+
+static char*(__fastcall* o_pSub_18003BC10)(void* a1, void* a2, void* a3, void* a4, void* a5, int a6) = nullptr;
+static char* __fastcall h_Sub_18003BC10(void* a1, void* a2, void* a3, void* a4, void* a5, int a6)
+{
+ HANDLE hThread;
+ char* ret = o_pSub_18003BC10(a1, a2, a3, a4, a5, a6);
+
+ if (ret != NULL && (hThread = reinterpret_cast<HANDLE>(*((uint64_t*)ret + 55))) != NULL)
+ {
+ HRESULT WINAPI _SetThreadDescription(HANDLE hThread, PCWSTR lpThreadDescription);
+ _SetThreadDescription(hThread, L"[Miles] WASAPI Service Thread");
+ }
+
+ return ret;
+}
+
ON_DLL_LOAD("mileswin64.dll", MilesWin64_Audio, (CModule module))
{
o_pLoadSampleMetadata = module.Offset(0xF110).RCast<decltype(o_pLoadSampleMetadata)>();
@@ -516,6 +550,12 @@ ON_DLL_LOAD("mileswin64.dll", MilesWin64_Audio, (CModule module))
o_pSub_1800294C0 = module.Offset(0x294C0).RCast<decltype(o_pSub_1800294C0)>();
HookAttach(&(PVOID&)o_pSub_1800294C0, (PVOID)h_Sub_1800294C0);
+
+ o_pSub_18003EBD0 = module.Offset(0x3EBD0).RCast<decltype(o_pSub_18003EBD0)>();
+ HookAttach(&(PVOID&)o_pSub_18003EBD0, (PVOID)h_Sub_18003EBD0);
+
+ o_pSub_18003BC10 = module.Offset(0x3BC10).RCast<decltype(o_pSub_18003BC10)>();
+ HookAttach(&(PVOID&)o_pSub_18003BC10, (PVOID)h_Sub_18003BC10);
}
ON_DLL_LOAD_RELIESON("engine.dll", MilesLogFuncHooks, ConVar, (CModule module))
diff --git a/primedev/core/tier0.cpp b/primedev/core/tier0.cpp
index dd5ac245..639b3bf8 100644
--- a/primedev/core/tier0.cpp
+++ b/primedev/core/tier0.cpp
@@ -18,11 +18,40 @@ void TryCreateGlobalMemAlloc()
g_pMemAllocSingleton = CreateGlobalMemAlloc(); // if it already exists, this returns the preexisting IMemAlloc instance
}
+HRESULT WINAPI _SetThreadDescription(HANDLE hThread, PCWSTR lpThreadDescription)
+{
+ // need to grab it dynamically as this function was only introduced at some point in Windows 10
+ static decltype(&SetThreadDescription) _SetThreadDescription =
+ CModule("KernelBase.dll").GetExportedFunction("SetThreadDescription").RCast<decltype(&SetThreadDescription)>();
+
+ if (_SetThreadDescription)
+ return _SetThreadDescription(hThread, lpThreadDescription);
+
+ return ERROR_OLD_WIN_VERSION;
+}
+
+static void(__fastcall* o_pThreadSetDebugName)(HANDLE threadHandle, const char* name) = nullptr;
+static void __fastcall h_ThreadSetDebugName(HANDLE threadHandle, const char* name)
+{
+ if (threadHandle == 0)
+ threadHandle = GetCurrentThread();
+
+ // TODO: This "method" of "charset conversion" from string to wstring is abhorrent. Change it to a proper one
+ // as soon as Northstar has some helper function to do proper charset conversions.
+ auto tmp = std::string(name);
+ _SetThreadDescription(threadHandle, std::wstring(tmp.begin(), tmp.end()).c_str());
+
+ o_pThreadSetDebugName(threadHandle, name);
+}
+
ON_DLL_LOAD("tier0.dll", Tier0GameFuncs, (CModule module))
{
// shouldn't be necessary, but do this just in case
TryCreateGlobalMemAlloc();
+ o_pThreadSetDebugName = module.GetExportedFunction("ThreadSetDebugName").RCast<decltype(o_pThreadSetDebugName)>();
+ HookAttach(&(PVOID&)o_pThreadSetDebugName, (PVOID)h_ThreadSetDebugName);
+
// setup tier0 funcs
CommandLine = module.GetExportedFunction("CommandLine").RCast<CommandLineType>();
Plat_FloatTime = module.GetExportedFunction("Plat_FloatTime").RCast<Plat_FloatTimeType>();