mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-10-31 09:20:21 +00:00
7caa87862e
All #ifndef guards on headers have been removed, I think, in favor of #pragma once Headers are now included as `#include "filename"` if the included file resides in the same directory as the file including it, or any subdirectory therein. Otherwise they are included as `#include <project/top/dir/relative/path/filename>` The above does not include system/os headers.
172 lines
5.1 KiB
C
172 lines
5.1 KiB
C
// there's probably an use case for a _newer_ implementation
|
|
// of pthread_setname_np(3), in fact, I may just merge _this_
|
|
// upstream...
|
|
#ifdef _MSC_VER
|
|
#include <windows.h>
|
|
|
|
typedef HRESULT(FAR PASCAL* p_SetThreadDescription)(void*, const wchar_t*);
|
|
#define EXCEPTION_SET_THREAD_NAME ((DWORD)0x406D1388)
|
|
|
|
typedef 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 */
|
|
} THREADNAME_INFO;
|
|
|
|
void
|
|
SetThreadName(DWORD dwThreadID, LPCSTR szThreadName)
|
|
{
|
|
THREADNAME_INFO info;
|
|
DWORD infosize;
|
|
HANDLE hThread;
|
|
/* because loonix is SHIT and limits thread names to 16 bytes */
|
|
wchar_t thr_name_w[16];
|
|
p_SetThreadDescription _SetThreadDescription;
|
|
|
|
/* current win10 flights now have a new named-thread API, let's try to use
|
|
* that first! */
|
|
/* first, dlsym(2) the new call from system library */
|
|
hThread = NULL;
|
|
_SetThreadDescription =
|
|
(p_SetThreadDescription)GetProcAddress(GetModuleHandle("kernel32"), "SetThreadDescription");
|
|
if (_SetThreadDescription)
|
|
{
|
|
/* grab another reference to the thread */
|
|
hThread = OpenThread(THREAD_SET_LIMITED_INFORMATION, FALSE, dwThreadID);
|
|
/* windows takes unicode, our input is utf-8 or plain ascii */
|
|
MultiByteToWideChar(CP_ACP, 0, szThreadName, -1, thr_name_w, 16);
|
|
if (hThread)
|
|
_SetThreadDescription(hThread, thr_name_w);
|
|
else
|
|
goto old; /* for whatever reason, we couldn't get a handle to the thread.
|
|
Just use the old method. */
|
|
}
|
|
else
|
|
{
|
|
old:
|
|
info.dwType = 0x1000;
|
|
info.szName = szThreadName;
|
|
info.dwThreadID = dwThreadID;
|
|
info.dwFlags = 0;
|
|
|
|
infosize = sizeof(info) / sizeof(DWORD);
|
|
|
|
__try
|
|
{
|
|
RaiseException(EXCEPTION_SET_THREAD_NAME, 0, infosize, (DWORD*)&info);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{}
|
|
}
|
|
/* clean up */
|
|
if (hThread)
|
|
CloseHandle(hThread);
|
|
}
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
#if 0
|
|
// Generate a core dump if we crash. Finally.
|
|
// Unix-style, we just leave a file named "core" in
|
|
// the user's working directory. Gets overwritten if
|
|
// a new crash occurs.
|
|
#include <dbghelp.h>
|
|
#ifdef _MSC_VER
|
|
#pragma comment(lib, "dbghelp.lib")
|
|
#endif
|
|
|
|
HRESULT
|
|
GenerateCrashDump(MINIDUMP_TYPE flags, EXCEPTION_POINTERS *seh)
|
|
{
|
|
HRESULT error = S_OK;
|
|
MINIDUMP_USER_STREAM_INFORMATION info = {0};
|
|
MINIDUMP_USER_STREAM stream = {0};
|
|
|
|
// get the time
|
|
SYSTEMTIME sysTime = {0};
|
|
GetSystemTime(&sysTime);
|
|
|
|
// get the computer name
|
|
char compName[MAX_COMPUTERNAME_LENGTH + 1] = {0};
|
|
DWORD compNameLen = ARRAYSIZE(compName);
|
|
GetComputerNameA(compName, &compNameLen);
|
|
|
|
// This information is written to a core dump user stream
|
|
char extra_info[1024] = {0};
|
|
snprintf(extra_info, 1024,
|
|
"hostname=%s;datetime=%02u-%02u-%02u_%02u-%02u-%02u", compName,
|
|
sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour,
|
|
sysTime.wMinute, sysTime.wSecond);
|
|
|
|
// open the file
|
|
HANDLE hFile =
|
|
CreateFileA("core", GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
|
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if(hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
error = GetLastError();
|
|
error = HRESULT_FROM_WIN32(error);
|
|
return error;
|
|
}
|
|
|
|
// get the process information
|
|
HANDLE hProc = GetCurrentProcess();
|
|
DWORD procID = GetCurrentProcessId();
|
|
|
|
// if we have SEH info, package it up
|
|
MINIDUMP_EXCEPTION_INFORMATION sehInfo = {0};
|
|
MINIDUMP_EXCEPTION_INFORMATION *sehPtr = NULL;
|
|
|
|
// Collect hostname and time
|
|
info.UserStreamCount = 1;
|
|
info.UserStreamArray = &stream;
|
|
stream.Type = CommentStreamA;
|
|
stream.BufferSize = strlen(extra_info) + 1;
|
|
stream.Buffer = extra_info;
|
|
|
|
if(seh)
|
|
{
|
|
sehInfo.ThreadId = GetCurrentThreadId();
|
|
sehInfo.ExceptionPointers = seh;
|
|
sehInfo.ClientPointers = FALSE;
|
|
sehPtr = &sehInfo;
|
|
}
|
|
|
|
// generate the crash dump
|
|
BOOL result =
|
|
MiniDumpWriteDump(hProc, procID, hFile, flags, sehPtr, &info, NULL);
|
|
if(!result)
|
|
{
|
|
error = (HRESULT)GetLastError(); // already an HRESULT
|
|
}
|
|
|
|
// close the file
|
|
CloseHandle(hFile);
|
|
return error;
|
|
}
|
|
|
|
// ok try a UNIX-style signal handler
|
|
LONG FAR PASCAL win32_signal_handler(EXCEPTION_POINTERS *e)
|
|
{
|
|
MessageBox(NULL,
|
|
"A fatal error has occurred. A core dump was generated and "
|
|
"dropped in the daemon's working directory. Please create an "
|
|
"issue at https://github.com/loki-network/loki-project, and "
|
|
"attach the core dump for further assistance.",
|
|
"Fatal Error", MB_ICONHAND);
|
|
GenerateCrashDump(
|
|
MiniDumpWithFullMemory | MiniDumpWithHandleData | MiniDumpWithThreadInfo
|
|
| MiniDumpWithProcessThreadData | MiniDumpWithFullMemoryInfo
|
|
| MiniDumpWithUnloadedModules | MiniDumpWithFullAuxiliaryState
|
|
| MiniDumpIgnoreInaccessibleMemory | MiniDumpWithTokenInformation,
|
|
e);
|
|
exit(127);
|
|
return 0;
|
|
}
|
|
#endif
|
|
#endif
|