From 2d6de01c39e1d15844a2e21937cda5e9b2e3040c Mon Sep 17 00:00:00 2001
From: goat <16760685+goaaats@users.noreply.github.com>
Date: Sat, 6 Jun 2020 18:41:42 +0200
Subject: [PATCH] feat: add DalamudDebugStub
---
Dalamud.sln | 13 ++
DalamudDebugStub/DalamudDebugStub.vcxproj | 171 ++++++++++++++++++
.../DalamudDebugStub.vcxproj.filters | 33 ++++
DalamudDebugStub/dllmain.cpp | 152 ++++++++++++++++
DalamudDebugStub/framework.h | 5 +
DalamudDebugStub/pch.cpp | 5 +
DalamudDebugStub/pch.h | 13 ++
7 files changed, 392 insertions(+)
create mode 100644 DalamudDebugStub/DalamudDebugStub.vcxproj
create mode 100644 DalamudDebugStub/DalamudDebugStub.vcxproj.filters
create mode 100644 DalamudDebugStub/dllmain.cpp
create mode 100644 DalamudDebugStub/framework.h
create mode 100644 DalamudDebugStub/pch.cpp
create mode 100644 DalamudDebugStub/pch.h
diff --git a/Dalamud.sln b/Dalamud.sln
index 43a5b0c8b..fb8b0c4af 100644
--- a/Dalamud.sln
+++ b/Dalamud.sln
@@ -23,6 +23,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Core", "lib\Dis
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.WebSocket", "lib\Discord.Net\src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj", "{AACDC15A-56F8-458F-9C73-DE89F60466AE}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DalamudDebugStub", "DalamudDebugStub\DalamudDebugStub.vcxproj", "{9FDA9A5C-50C6-4333-8DCE-DFEB89363F2A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -129,6 +131,17 @@ Global
{AACDC15A-56F8-458F-9C73-DE89F60466AE}.Release|x64.Build.0 = Release|Any CPU
{AACDC15A-56F8-458F-9C73-DE89F60466AE}.Release|x86.ActiveCfg = Release|Any CPU
{AACDC15A-56F8-458F-9C73-DE89F60466AE}.Release|x86.Build.0 = Release|Any CPU
+ {9FDA9A5C-50C6-4333-8DCE-DFEB89363F2A}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {9FDA9A5C-50C6-4333-8DCE-DFEB89363F2A}.Debug|Any CPU.Build.0 = Debug|x64
+ {9FDA9A5C-50C6-4333-8DCE-DFEB89363F2A}.Debug|x64.ActiveCfg = Debug|x64
+ {9FDA9A5C-50C6-4333-8DCE-DFEB89363F2A}.Debug|x64.Build.0 = Debug|x64
+ {9FDA9A5C-50C6-4333-8DCE-DFEB89363F2A}.Debug|x86.ActiveCfg = Debug|Win32
+ {9FDA9A5C-50C6-4333-8DCE-DFEB89363F2A}.Debug|x86.Build.0 = Debug|Win32
+ {9FDA9A5C-50C6-4333-8DCE-DFEB89363F2A}.Release|Any CPU.ActiveCfg = Release|Win32
+ {9FDA9A5C-50C6-4333-8DCE-DFEB89363F2A}.Release|x64.ActiveCfg = Release|x64
+ {9FDA9A5C-50C6-4333-8DCE-DFEB89363F2A}.Release|x64.Build.0 = Release|x64
+ {9FDA9A5C-50C6-4333-8DCE-DFEB89363F2A}.Release|x86.ActiveCfg = Release|Win32
+ {9FDA9A5C-50C6-4333-8DCE-DFEB89363F2A}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/DalamudDebugStub/DalamudDebugStub.vcxproj b/DalamudDebugStub/DalamudDebugStub.vcxproj
new file mode 100644
index 000000000..9a2747fd3
--- /dev/null
+++ b/DalamudDebugStub/DalamudDebugStub.vcxproj
@@ -0,0 +1,171 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ {9FDA9A5C-50C6-4333-8DCE-DFEB89363F2A}
+ Win32Proj
+ DalamudDebugStub
+ 10.0
+
+
+
+ DynamicLibrary
+ true
+ v142
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v142
+ true
+ Unicode
+
+
+ DynamicLibrary
+ true
+ v142
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+ $(SolutionDir)bin\
+
+
+ false
+
+
+ false
+
+
+
+ Use
+ Level3
+ true
+ WIN32;_DEBUG;DALAMUDDEBUGSTUB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Windows
+ true
+ false
+
+
+
+
+ Use
+ Level3
+ true
+ _DEBUG;DALAMUDDEBUGSTUB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Windows
+ true
+ false
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dbghelp.lib;%(AdditionalDependencies)
+
+
+
+
+ Use
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;DALAMUDDEBUGSTUB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Windows
+ true
+ true
+ true
+ false
+
+
+
+
+ Use
+ Level3
+ true
+ true
+ true
+ NDEBUG;DALAMUDDEBUGSTUB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Windows
+ true
+ true
+ true
+ false
+
+
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DalamudDebugStub/DalamudDebugStub.vcxproj.filters b/DalamudDebugStub/DalamudDebugStub.vcxproj.filters
new file mode 100644
index 000000000..d4f9881b8
--- /dev/null
+++ b/DalamudDebugStub/DalamudDebugStub.vcxproj.filters
@@ -0,0 +1,33 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/DalamudDebugStub/dllmain.cpp b/DalamudDebugStub/dllmain.cpp
new file mode 100644
index 000000000..2aa1de7a2
--- /dev/null
+++ b/DalamudDebugStub/dllmain.cpp
@@ -0,0 +1,152 @@
+// dllmain.cpp : Defines the entry point for the DLL application.
+#include "pch.h"
+
+#include
+#include
+#include
+#include
+#include
+
+BOOL ListProcessThreads(DWORD dwOwnerPID)
+{
+ HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
+ THREADENTRY32 te32;
+
+ // Take a snapshot of all running threads
+ hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+ if (hThreadSnap == INVALID_HANDLE_VALUE)
+ return(FALSE);
+
+ // Fill in the size of the structure before using it.
+ te32.dwSize = sizeof(THREADENTRY32);
+
+ // Retrieve information about the first thread,
+ // and exit if unsuccessful
+ if (!Thread32First(hThreadSnap, &te32))
+ {
+ CloseHandle(hThreadSnap); // Must clean up the snapshot object!
+ return(FALSE);
+ }
+
+ // Now walk the thread list of the system,
+ // and display information about each thread
+ // associated with the specified process
+ do
+ {
+ if (te32.th32OwnerProcessID == dwOwnerPID && te32.th32ThreadID != GetCurrentThreadId())
+ {
+ _tprintf(TEXT("\n THREAD ID = 0x%08X"), te32.th32ThreadID);
+ _tprintf(TEXT("\n base priority = %d"), te32.tpBasePri);
+ _tprintf(TEXT("\n delta priority = %d"), te32.tpDeltaPri);
+ SuspendThread(OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID));
+ }
+ } while (Thread32Next(hThreadSnap, &te32));
+
+ _tprintf(TEXT("\n"));
+
+ // Don't forget to clean up the snapshot object.
+ CloseHandle(hThreadSnap);
+ return(TRUE);
+}
+
+bool isExcept = false;
+
+LONG WINAPI
+VectoredHandlerSkip1(
+ struct _EXCEPTION_POINTERS* ExceptionInfo
+)
+{
+ PEXCEPTION_RECORD Record = ExceptionInfo->ExceptionRecord;
+
+ if (Record->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ //ListProcessThreads(GetCurrentProcessId());
+
+ if (!isExcept)
+ {
+ isExcept = true;
+
+ TCHAR pszMessage[1024] = { 0 };
+ _stprintf_s(pszMessage, _T("An internal error in Dalamud or a FFXIV plugin occured.\nThe game must close.\n\nDo you wish to save troubleshooting information?\n\nReasoning: 0x%x at 0x%x"), Record->ExceptionCode, Record->ExceptionAddress);
+
+ auto res = MessageBox(NULL, pszMessage, L"Dalamud", MB_YESNO | MB_ICONERROR | MB_TOPMOST);
+
+ if (res == IDYES)
+ {
+
+ TCHAR fileName[255] = { 0 };
+
+ SYSTEMTIME t;
+ GetSystemTime(&t);
+ _stprintf_s(fileName, _T("MD-%d-%d-%d-%d-%d-%d.dmp"), t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
+
+ HANDLE hFile = CreateFile(fileName, GENERIC_READ | GENERIC_WRITE,
+ 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
+ {
+ // Create the minidump
+
+ MINIDUMP_EXCEPTION_INFORMATION mdei;
+
+ mdei.ThreadId = GetCurrentThreadId();
+ mdei.ExceptionPointers = ExceptionInfo;
+ mdei.ClientPointers = TRUE;
+
+ BOOL rv = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
+ hFile, (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithDataSegs | MiniDumpWithThreadInfo), (ExceptionInfo != 0) ? &mdei : 0, 0, 0);
+
+ if (!rv)
+ _stprintf_s(pszMessage, _T("MiniDumpWriteDump failed. Error: %u \n"), GetLastError());
+ else
+ _stprintf_s(pszMessage, _T("Minidump created.\n"));
+
+ MessageBox(NULL, pszMessage, L"Dalamud", MB_OK | MB_ICONINFORMATION | MB_TOPMOST);
+
+ // Close the file
+
+ CloseHandle(hFile);
+ }
+ else
+ {
+ _tprintf(_T("CreateFile failed. Error: %u \n"), GetLastError());
+ }
+ }
+
+ exit(-1);
+ }
+
+ PCONTEXT Context;
+
+ Context = ExceptionInfo->ContextRecord;
+#ifdef _AMD64_
+ Context->Rip++;
+#else
+ Context->Eip++;
+#endif
+ return EXCEPTION_CONTINUE_EXECUTION;
+}
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
+)
+{
+ TCHAR pszMessage[1024] = { 0 };
+
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ _stprintf_s(pszMessage, _T("GetCurrentProcessId() %d, hModule 0x%p, nReason %d\r\n"), GetCurrentProcessId(), hModule, ul_reason_for_call);
+ OutputDebugString(pszMessage);
+ AddVectoredExceptionHandler(99, VectoredHandlerSkip1);
+ break;
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
diff --git a/DalamudDebugStub/framework.h b/DalamudDebugStub/framework.h
new file mode 100644
index 000000000..54b83e94f
--- /dev/null
+++ b/DalamudDebugStub/framework.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+// Windows Header Files
+#include
diff --git a/DalamudDebugStub/pch.cpp b/DalamudDebugStub/pch.cpp
new file mode 100644
index 000000000..64b7eef6d
--- /dev/null
+++ b/DalamudDebugStub/pch.cpp
@@ -0,0 +1,5 @@
+// pch.cpp: source file corresponding to the pre-compiled header
+
+#include "pch.h"
+
+// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
diff --git a/DalamudDebugStub/pch.h b/DalamudDebugStub/pch.h
new file mode 100644
index 000000000..885d5d62e
--- /dev/null
+++ b/DalamudDebugStub/pch.h
@@ -0,0 +1,13 @@
+// pch.h: This is a precompiled header file.
+// Files listed below are compiled only once, improving build performance for future builds.
+// This also affects IntelliSense performance, including code completion and many code browsing features.
+// However, files listed here are ALL re-compiled if any one of them is updated between builds.
+// Do not add files here that you will be updating frequently as this negates the performance advantage.
+
+#ifndef PCH_H
+#define PCH_H
+
+// add headers that you want to pre-compile here
+#include "framework.h"
+
+#endif //PCH_H