@@ -81,9 +81,10 @@
*
**********************************************************************/
#include <windows.h>
#include <tchar.h>
#include <wchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <QSysInfo>
//#pragma comment(lib, "version.lib") // for "VerQueryValue"
//#pragma warning(disable:4826)

@@ -230,15 +231,14 @@ DWORD64


// secure-CRT_functions are only available starting with VC8
/*
#if _MSC_VER < 1400
#define strcpy_s(dst, len, src) strcpy(dst, src)
#define strncpy_s(dst, len, src, maxLen) strncpy(dst, len, src)
#define strncpy_s(dst, len, src, maxLen) strncpy(dst, src, maxLen)
#define strcat_s(dst, len, src) strcat(dst, src)
#define _snprintf_s _snprintf
#define sprintf_s snprintf
//#define _tcscat_s _tcscat
#endif
*/



static void MyStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc)
{
if (nMaxDestSize <= 0) return;
@@ -291,64 +291,71 @@ class StackWalkerInternal
return FALSE;
// Dynamically load the Entry-Points for dbghelp.dll:
// First try to load the newsest one from
TCHAR szTemp[4096];

std::wstring szTemp;
// But before wqe do this, we first check if the ".local" file exists
if (GetModuleFileName(NULL, szTemp, 4096) > 0)
wchar_t* szTempS = (wchar_t*)szTemp.c_str();
if (GetModuleFileName(NULL, szTempS, 4096) > 0)
{
wcscat_s(szTemp, L".local");
if (GetFileAttributes(szTemp) == INVALID_FILE_ATTRIBUTES)
szTemp += L".local";
if (GetFileAttributes(szTemp.c_str()) == INVALID_FILE_ATTRIBUTES)
{
// ".local" file does not exist, so we can try to load the dbghelp.dll from the "Debugging Tools for Windows"
// Ok, first try the new path according to the archtitecture:
#ifdef _M_IX86
if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(L"ProgramFiles", szTemp, 4096) > 0) )
if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(L"ProgramFiles", szTempS, 4096) > 0) )
{
wcscat_s(szTemp, L"\\Debugging Tools for Windows (x86)\\dbghelp.dll");
szTemp = szTemp + L"\\Debugging Tools for Windows (x86)\\dbghelp.dll";
szTempS = (wchar_t*)szTemp.c_str();
// now check if the file exists:
if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
if (GetFileAttributes(szTemp.c_str()) != INVALID_FILE_ATTRIBUTES)
{
m_hDbhHelp = LoadLibrary(szTemp);
m_hDbhHelp = LoadLibrary(szTemp.c_str());
}
}
#elif _M_X64
if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) )
{
_tcscat_s(szTemp, _T("\\Debugging Tools for Windows (x64)\\dbghelp.dll"));
szTemp += L"\\Debugging Tools for Windows (x64)\\dbghelp.dll";
szTempS = (wchar_t*)szTemp.c_str();
// now check if the file exists:
if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
if (GetFileAttributes(szTemp.c_str()) != INVALID_FILE_ATTRIBUTES)
{
m_hDbhHelp = LoadLibrary(szTemp);
m_hDbhHelp = LoadLibrary(szTemp.c_str());
}
}
#elif _M_IA64
if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) )
{
_tcscat_s(szTemp, _T("\\Debugging Tools for Windows (ia64)\\dbghelp.dll"));
szTemp += L"\\Debugging Tools for Windows (ia64)\\dbghelp.dll";
szTempS = (wchar_t*)szTemp.c_str();
// now check if the file exists:
if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
if (GetFileAttributes(szTempS) != INVALID_FILE_ATTRIBUTES)
{
m_hDbhHelp = LoadLibrary(szTemp);
m_hDbhHelp = LoadLibrary(szTempS);
}
}
#endif
// If still not found, try the old directories...
if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(L"ProgramFiles", szTemp, 4096) > 0) )
if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(L"ProgramFiles", szTempS, 4096) > 0) )
{
wcscat_s(szTemp, L"\\Debugging Tools for Windows\\dbghelp.dll");
szTemp += L"\\Debugging Tools for Windows\\dbghelp.dll";
szTempS = (wchar_t*)szTemp.c_str();
// now check if the file exists:
if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
if (GetFileAttributes(szTempS) != INVALID_FILE_ATTRIBUTES)
{
m_hDbhHelp = LoadLibrary(szTemp);
m_hDbhHelp = LoadLibrary(szTempS);
}
}
#if defined _M_X64 || defined _M_IA64
// Still not found? Then try to load the (old) 64-Bit version:
if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTemp, 4096) > 0) )
if ( (m_hDbhHelp == NULL) && (GetEnvironmentVariable(_T("ProgramFiles"), szTempS, 4096) > 0) )
{
_tcscat_s(szTemp, _T("\\Debugging Tools for Windows 64-Bit\\dbghelp.dll"));
if (GetFileAttributes(szTemp) != INVALID_FILE_ATTRIBUTES)
szTemp += L"\\Debugging Tools for Windows 64-Bit\\dbghelp.dll";
szTempS = (wchar_t*)szTemp.c_str();
if (GetFileAttributes(szTempS) != INVALID_FILE_ATTRIBUTES)
{
m_hDbhHelp = LoadLibrary(szTemp);
m_hDbhHelp = LoadLibrary(szTempS);
}
}
#endif
@@ -558,7 +565,7 @@ struct IMAGEHLP_MODULE64_V2 {
typedef BOOL (__stdcall *tM32N)(HANDLE hSnapshot, LPMODULEENTRY32 lpme);

// try both dlls...
const TCHAR *dllname[] = { L"kernel32.dll", L"tlhelp32.dll" };
const wchar_t *dllname[] = { L"kernel32.dll", L"tlhelp32.dll" };
HINSTANCE hToolhelp = NULL;
tCT32S pCT32S = NULL;
tM32F pM32F = NULL;
@@ -732,7 +739,7 @@ struct IMAGEHLP_MODULE64_V2 {
if (GetFileVersionInfoA(szImg, dwHandle, dwSize, vData) != 0)
{
UINT len;
TCHAR szSubBlock[] = L"\\";
wchar_t szSubBlock[] = L"\\";
if (VerQueryValue(vData, szSubBlock, (LPVOID*) &fInfo, &len) == 0)
fInfo = NULL;
else
@@ -1005,7 +1012,6 @@ BOOL StackWalker::LoadModules()
return bRet;
}


// The following is used to pass the "userData"-Pointer to the user-provided readMemoryFunction
// This has to be done due to a problem with the "hProcess"-parameter in x64...
// Because this class is in no case multi-threading-enabled (because of the limitations
@@ -1040,12 +1046,12 @@ BOOL StackWalker::ShowCallstack(HANDLE hThread, const CONTEXT *context, PReadPro
{
// If no context is provided, capture the context
// See: https://stackwalker.codeplex.com/discussions/446958
#if _WIN32_WINNT <= 0x0501
//#if _WIN32_WINNT <= 0x0501
// If we need to support XP, we need to use the "old way", because "GetThreadId" is not available!
if (hThread == GetCurrentThread())
#else
if (GetThreadId(hThread) == GetCurrentThreadId())
#endif
//#else
// if (GetThreadId_My(hThread) == GetCurrentThreadId())
//#endif
{
GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, USED_CONTEXT_FLAGS);
}
@@ -1281,15 +1287,15 @@ BOOL __stdcall StackWalker::myReadProcMem(
void StackWalker::OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion)
{
CHAR buffer[STACKWALK_MAX_NAMELEN];
if (fileVersion == 0)
_snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s'\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName);
if(fileVersion == 0)
sprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %ld (result: %ld), SymType: '%s', PDB: '%s'\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName);
else
{
DWORD v4 = (DWORD) (fileVersion & 0xFFFF);
DWORD v3 = (DWORD) ((fileVersion>>16) & 0xFFFF);
DWORD v2 = (DWORD) ((fileVersion>>32) & 0xFFFF);
DWORD v1 = (DWORD) ((fileVersion>>48) & 0xFFFF);
_snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s', fileVersion: %d.%d.%d.%d\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName, v1, v2, v3, v4);
sprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s:%s (%p), size: %ld (result: %ld), SymType: '%s', PDB: '%s', fileVersion: %ld.%ld.%ld.%ld\n", img, mod, (LPVOID) baseAddr, size, result, symType, pdbName, v1, v2, v3, v4);
}
OnOutput(buffer);
}
@@ -1310,10 +1316,10 @@ void StackWalker::OnCallstackEntry(CallstackEntryType eType, CallstackEntry &ent
MyStrCpy(entry.lineFileName, STACKWALK_MAX_NAMELEN, "(filename not available)");
if (entry.moduleName[0] == 0)
MyStrCpy(entry.moduleName, STACKWALK_MAX_NAMELEN, "(module-name not available)");
_snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%p (%s): %s: %s\n", (LPVOID) entry.offset, entry.moduleName, entry.lineFileName, entry.name);
sprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%p (%s): %s: %s\n", (LPVOID) entry.offset, entry.moduleName, entry.lineFileName, entry.name);
}
else
_snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s (%d): %s\n", entry.lineFileName, entry.lineNumber, entry.name);
sprintf_s(buffer, STACKWALK_MAX_NAMELEN, "%s (%ld): %s\n", entry.lineFileName, entry.lineNumber, entry.name);
buffer[STACKWALK_MAX_NAMELEN-1] = 0;
OnOutput(buffer);
}
@@ -1323,15 +1329,15 @@ void StackWalker::OnDbgHelpErr(LPCSTR /*szFuncName*/, DWORD /*gle*/, DWORD64 /*a
{
/*
CHAR buffer[STACKWALK_MAX_NAMELEN];
_snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "ERROR: %s, GetLastError: %d (Address: %p)\n", szFuncName, gle, (LPVOID) addr);
sprintf_s(buffer, STACKWALK_MAX_NAMELEN, "ERROR: %s, GetLastError: %d (Address: %p)\n", szFuncName, gle, (LPVOID) addr);
OnOutput(buffer);
*/
}

void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName)
{
CHAR buffer[STACKWALK_MAX_NAMELEN];
_snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n", szSearchPath, symOptions, szUserName);
sprintf_s(buffer, STACKWALK_MAX_NAMELEN, "SymInit: Symbol-SearchPath: '%s', symOptions: %ld, UserName: '%s'\n", szSearchPath, symOptions, szUserName);
OnOutput(buffer);
// Also display the OS-version
#if _MSC_VER <= 1200
@@ -1340,7 +1346,7 @@ void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUser
ver.dwOSVersionInfoSize = sizeof(ver);
if (GetVersionExA(&ver) != FALSE)
{
_snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s)\n",
sprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %ld.%ld.%ld (%s)\n",
ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber,
ver.szCSDVersion);
OnOutput(buffer);
@@ -1352,7 +1358,7 @@ void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUser
#pragma warning(suppress: 28159) //API
if (GetVersionExA( (OSVERSIONINFOA*) &ver) != FALSE)
{
_snprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n",
sprintf_s(buffer, STACKWALK_MAX_NAMELEN, "OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n",
ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber,
ver.szCSDVersion, ver.wSuiteMask, ver.wProductType);
OnOutput(buffer);