Skip to content

Commit

Permalink
Don't use __try/__except to name threads using the msvc debugger
Browse files Browse the repository at this point in the history
Manually set/unset the handler with AddVectoredExceptionHandler/RemoveVectoredExceptionHandler so that the code can be used with mingw as well, there are no functional differences
  • Loading branch information
edo9300 committed Aug 10, 2023
1 parent f11dba7 commit cc9b899
Showing 1 changed file with 16 additions and 17 deletions.
33 changes: 16 additions & 17 deletions gframe/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,41 +66,40 @@ constexpr FileMode FileStream::app;
#if EDOPRO_WINDOWS
namespace {

#if defined(_MSC_VER)
//https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code?view=vs-2015&redirectedfrom=MSDN

static constexpr DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma warning(push)
#pragma warning(disable: 6320 6322)
#pragma pack(push, 8)
struct THREADNAME_INFO {
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
};
#pragma pack(pop)

LONG NTAPI PvectoredExceptionHandler(EXCEPTION_POINTERS* ExceptionInfo) {
(void)ExceptionInfo;
return EXCEPTION_CONTINUE_EXECUTION;
}

inline void NameThreadMsvc(const char* threadName) {
const THREADNAME_INFO info{ 0x1000, threadName, ((DWORD)-1), 0 };
__try { RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); }
__except(EXCEPTION_EXECUTE_HANDLER) {}
constexpr DWORD MS_VC_EXCEPTION = 0x406D1388;
const THREADNAME_INFO info{ 0x1000, threadName, static_cast<DWORD>(-1), 0 };
auto handle = AddVectoredExceptionHandler(1, PvectoredExceptionHandler);
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), reinterpret_cast<const ULONG_PTR*>(&info));
RemoveVectoredExceptionHandler(handle);
}
#pragma warning(pop)
#endif

const auto PSetThreadDescription = [] {
auto proc = GetProcAddress(GetModuleHandle(EPRO_TEXT("kernel32.dll")), "SetThreadDescription");
if(proc == nullptr)
proc = GetProcAddress(GetModuleHandle(EPRO_TEXT("KernelBase.dll")), "SetThreadDescription");
using SetThreadDescription_t = HRESULT(WINAPI*)(HANDLE, PCWSTR);
return function_cast<SetThreadDescription_t>(proc);
}();

void NameThread(const char* name, const wchar_t* wname) {
(void)name;
NameThreadMsvc(name);
if(PSetThreadDescription)
PSetThreadDescription(GetCurrentThread(), wname);
#if defined(_MSC_VER)
NameThreadMsvc(name);
#endif //_MSC_VER
}

//Dump creation routines taken from Postgres
Expand Down Expand Up @@ -148,7 +147,7 @@ LONG WINAPI crashDumpHandler(EXCEPTION_POINTERS* pExceptionInfo) {
}

auto systemTicks = GetTickCount();
const auto dumpPath = fmt::sprintf(EPRO_TEXT("./crashdumps/EDOPro-pid%0i-%0i.mdmp"), (int)selfPid, (int)systemTicks);
const auto dumpPath = epro::sprintf(EPRO_TEXT("./crashdumps/EDOPro-pid%0i-%0i.mdmp"), (int)selfPid, (int)systemTicks);

auto dumpFile = CreateFile(dumpPath.data(), GENERIC_WRITE, FILE_SHARE_WRITE,
nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
Expand All @@ -160,7 +159,7 @@ LONG WINAPI crashDumpHandler(EXCEPTION_POINTERS* pExceptionInfo) {
}

if(miniDumpWriteDumpFn(selfProcHandle, selfPid, dumpFile, dumpType, &ExInfo, nullptr, nullptr))
ygo::GUIUtils::ShowErrorWindow("Crash dump", fmt::format("Succesfully wrote crash dump to file \"{}\"\n", ygo::Utils::ToUTF8IfNeeded(dumpPath)));
ygo::GUIUtils::ShowErrorWindow("Crash dump", epro::format("Succesfully wrote crash dump to file \"{}\"\n", ygo::Utils::ToUTF8IfNeeded(dumpPath)));

CloseHandle(dumpFile);
FreeLibrary(dbgHelpDLL);
Expand Down

0 comments on commit cc9b899

Please sign in to comment.