@@ -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);