From 78325572c1b2ae617dd5502ab726bfded1fd0506 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Wed, 4 Jun 2025 23:27:56 +0100 Subject: Add some WinDbg helpers and tidy up the README --- .gitignore | 1 - README | 27 ++++++++++++++++++++++----- tools/steamfix.bat | 27 +++++++++++++++++++++++++++ tools/windbg/.gitignore | 1 + tools/windbg/initcmds | 6 ++++++ tools/windbg/install.ps1 | 44 ++++++++++++++++++++++++++++++++++++++++++++ tools/windbg/natvis.xml | 5 +++++ tools/windbg/windbg.bat | 16 ++++++++++++++++ 8 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 tools/steamfix.bat create mode 100644 tools/windbg/.gitignore create mode 100644 tools/windbg/initcmds create mode 100644 tools/windbg/install.ps1 create mode 100644 tools/windbg/natvis.xml create mode 100644 tools/windbg/windbg.bat diff --git a/.gitignore b/.gitignore index d880120..08d5f85 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ /.build/ /sst.dll -/sst.pdb /sst.so /compile_commands.json /compile_flags.txt diff --git a/README b/README index df7aac0..af0b2b6 100644 --- a/README +++ b/README @@ -19,16 +19,33 @@ Windows: Linux: • Install Clang (and LLD) via your system package manager. Technically, GCC should be able to compile most of this too, but we are currently relying on - a Clang-specific extension or two, and GCC in general doesn't get tested nor - used for binary releases, so it's probably not worth wasting time on. + a Clang-specific extension or two, and GCC in general doesn’t get tested nor + used for binary releases, so it’s probably not worth wasting time on. • Install 32-bit glibc and libstdc++ libraries and associated C headers if they’re not already installed. • Run ./compile (in lieu of a better build tool, to be added later). NOTE: Linux code should maybe compile now but still crashes on cvar registration and almost none of the features usefully work. In other words, it needs quite a -lot more development before it's of use to anyone. It's also not actively tested -really so don't be surprised if it doesn't compile at all again at some point. +lot more development before it’s of use to anyone. It’s also not actively tested +really so don’t be surprised if it doesn’t compile at all again at some point. + +════ Debugging ════ + +On Windows, SST’s preferred debugger is WinDBG (specifically the new frontend), +because it does everything we need, is free, and isn’t horribly slow usually. + +The script tools/windbg/windbg.bat will automatically download the latest +version into tools/windbg/bin and run it. Alternatively, if you already have a +copy, set the environment variable WINDBG_BIN and that copy will be used +instead. + +NatVis definitions are contained in tools/windbg/natvis.xml. Currently there is +not much in there but it can be expanded as and when useful things come up. + +Note that after debugging some specific games (mainly some old versions of Left +4 Dead 2) it may be necessary to run tools/steamfix.bat to make other Steam +games launch correctly again. ════ How and where to install ════ @@ -49,7 +66,7 @@ make a directory for SST in the top-level engine directory and do for instance `plugin_load ../SST/sst`. The way the paths work out, that always works no matter what, and also avoids cluttering up your game files. -When actively developing the plugin, it's possible to back out of the game +When actively developing the plugin, it’s possible to back out of the game installation with `../../` etcetera and load from anywhere you want, as long as it’s not on a different Windows drive letter. This is essentially the best way to work with SST built from source as it avoids the need to copy it to different diff --git a/tools/steamfix.bat b/tools/steamfix.bat new file mode 100644 index 0000000..d0a77c2 --- /dev/null +++ b/tools/steamfix.bat @@ -0,0 +1,27 @@ +:: This file is dedicated to the public domain. +@echo off + +:: In several old L4D2 builds, we currently have some weird black magic we don't +:: fully understand to do what looks like DRM circumvention or... something. +:: Annoyingly, that black magic manages to break regular use of Steam after the +:: game exits. This is fixed by setting a registry key back to Steam's PID. + +:: The scripts used to launch those builds already do this, of course, but if +:: you're launching L4D2 under a debugger, you can use this script instead. + +:: By the way, if anyone wants to look into solving the root cause so that none +:: of this is needed any more, that would be cool! + +set REG=%SYSTEMROOT%\SysWOW64\reg.exe +if not exist "%REG%" set REG=%SYSTEMROOT%\System32\reg.exe +set steampid= +for /F "usebackq skip=1 delims=" %%I in ( + `wmic process where "name='steam.exe'" get processid 2^>nul` +) do ( set steampid=%%I & goto :ok) +:ok +if not %steampid%=="" ( + %REG% add "HKCU\SOFTWARE\Valve\Steam\ActiveProcess" /f /t REG_DWORD ^ +/v pid /d %steampid%>nul +) + +:: vi: sw=4 ts=4 noet tw=80 cc=80 diff --git a/tools/windbg/.gitignore b/tools/windbg/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/tools/windbg/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/tools/windbg/initcmds b/tools/windbg/initcmds new file mode 100644 index 0000000..fe0f62f --- /dev/null +++ b/tools/windbg/initcmds @@ -0,0 +1,6 @@ +.nvload tools\windbg\natvis.xml + +$$ Emulate Source Thread Fix for high-core-count systems by breaking on +$$ GetSystemInfo, grabbing the struct pointer from the stack, then fiddling +$$ with its contents upon returning to the caller. +bp kernelbase!GetSystemInfo "dx @$t1 = *(void **)(@esp + 4); bp /1 @$ra \"dx @$t2 = ((_SYSTEM_INFO *)@$t1)->dwNumberOfProcessors; dx ((_SYSTEM_INFO *)@$t1)->dwNumberOfProcessors = @$t2 > 24 ? 24 : @$t2; g\"; g" diff --git a/tools/windbg/install.ps1 b/tools/windbg/install.ps1 new file mode 100644 index 0000000..4e206e0 --- /dev/null +++ b/tools/windbg/install.ps1 @@ -0,0 +1,44 @@ +# This script is dedicated to the public domain. + +Add-Type -Assembly System.IO.Compression.FileSystem + +$OutDir = "tools\windbg\bin" +$Arch = "x64" # can also use x86, arm64 + +if (!(Test-Path $OutDir)) { $null = mkdir $OutDir } +[xml]$content = (New-Object System.Net.WebClient).DownloadString("https://aka.ms/windbg/download") +$bundleurl = $content.AppInstaller.MainBundle.Uri +# Using curl.exe here instead because it has an actual useful progress bar. +# Modern PowerShell does too, but not the PS 5.1 that still ships with W10 +#Invoke-WebRequest $bundleurl -OutFile $OutDir\__bundle.zip +curl.exe "-#o$OutDir\__bundle.zip" "$bundleurl" +$filename = switch ($Arch) { + "x64" { "windbg_win-x64.msix" } + "x86" { "windbg_win-x86.msix" } + "arm64" { "windbg_win-arm64.msix" } +} +$zip = [IO.Compression.ZipFile]::OpenRead("$OutDir\__bundle.zip") +try { + if ($found = $zip.Entries.Where({ $_.FullName -eq $filename }, "First") ) { + $dest = "$OutDir\__msix.zip" + [IO.Compression.ZipFileExtensions]::ExtractToFile($found[0], $dest, $false) + } + else { + Write-Error "File not found in ZIP: $filename" + exit 100 + } +} +finally { + if ($zip) { $zip.Dispose() } +} +rm $OutDir\__bundle.zip +Expand-Archive -DestinationPath "$OutDir" "$OutDir\__msix.zip" +rm $OutDir\__msix.zip +# misc cleanup +rm -r $OutDir\AppxMetadata\ +rm $OutDir\'``[Content_Types``].xml' # wtf, microsoft, wtf. +rm $OutDir\AppxBlockMap.xml +rm $OutDir\AppxManifest.xml +rm $OutDir\AppxSignature.p7x +rm -r $OutDir\runtimes\unix\ +mv "$OutDir\Third%20Party%20Notices.txt" "$OutDir\Third Party Notices.txt" diff --git a/tools/windbg/natvis.xml b/tools/windbg/natvis.xml new file mode 100644 index 0000000..159b4d0 --- /dev/null +++ b/tools/windbg/natvis.xml @@ -0,0 +1,5 @@ + + + + ConVar: {strval} + diff --git a/tools/windbg/windbg.bat b/tools/windbg/windbg.bat new file mode 100644 index 0000000..11cf29c --- /dev/null +++ b/tools/windbg/windbg.bat @@ -0,0 +1,16 @@ +:: This file is dedicated to the public domain. +@echo off +setlocal + +if not "%WINDBG_BIN%"=="" goto :ok +set WINDBG_BIN=tools\windbg\bin +if exist tools\windbg\bin\DbgX.Shell.exe goto :ok +powershell tools\windbg\install.ps1 || goto :end + +:ok +%WINDBG_BIN%\DbgX.Shell.exe /g /c $^