Fix Win32 stack traces issue due to invalid search path for debug symbols
#457
This commit is contained in:
@@ -38,7 +38,7 @@ namespace
|
|||||||
CriticalSection SymLocker;
|
CriticalSection SymLocker;
|
||||||
bool SymInitialized = false;
|
bool SymInitialized = false;
|
||||||
bool SymModulesDirty = true;
|
bool SymModulesDirty = true;
|
||||||
char* SymPath = nullptr;
|
Array<String> SymbolsPath;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,9 +617,8 @@ void WindowsPlatform::Exit()
|
|||||||
{
|
{
|
||||||
SymInitialized = false;
|
SymInitialized = false;
|
||||||
SymCleanup(GetCurrentProcess());
|
SymCleanup(GetCurrentProcess());
|
||||||
free(SymPath);
|
|
||||||
SymPath = nullptr;
|
|
||||||
}
|
}
|
||||||
|
SymbolsPath.Resize(0);
|
||||||
SymLocker.Unlock();
|
SymLocker.Unlock();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1116,7 +1115,13 @@ void* WindowsPlatform::LoadLibrary(const Char* filename)
|
|||||||
#if CRASH_LOG_ENABLE
|
#if CRASH_LOG_ENABLE
|
||||||
// Refresh modules info during next stack trace collecting to have valid debug symbols information
|
// Refresh modules info during next stack trace collecting to have valid debug symbols information
|
||||||
SymLocker.Lock();
|
SymLocker.Lock();
|
||||||
SymModulesDirty = true;
|
const auto folder = StringUtils::GetDirectoryName(filename);
|
||||||
|
if (!SymbolsPath.Contains(folder))
|
||||||
|
SymbolsPath.Add(folder);
|
||||||
|
if (SymInitialized)
|
||||||
|
{
|
||||||
|
SymModulesDirty = true;
|
||||||
|
}
|
||||||
SymLocker.Unlock();
|
SymLocker.Unlock();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1137,80 +1142,43 @@ Array<PlatformBase::StackFrame> WindowsPlatform::GetStackFrames(int32 skipCount,
|
|||||||
SymInitialized = true;
|
SymInitialized = true;
|
||||||
|
|
||||||
// Build search path
|
// Build search path
|
||||||
const size_t nSymPathLen = 4096;
|
String symbolSearchPath;
|
||||||
SymPath = (char*)malloc(nSymPathLen);
|
TCHAR ModulePath[MAX_PATH] = { 0 };
|
||||||
SymPath[0] = 0;
|
if (::GetModuleFileName(::GetModuleHandle(nullptr), ModulePath, MAX_PATH))
|
||||||
strcat_s(SymPath, nSymPathLen, ".;");
|
|
||||||
const size_t nTempLen = 1024;
|
|
||||||
char szTemp[nTempLen];
|
|
||||||
|
|
||||||
// Current directory path
|
|
||||||
if (GetCurrentDirectoryA(nTempLen, szTemp) > 0)
|
|
||||||
{
|
{
|
||||||
szTemp[nTempLen - 1] = 0;
|
symbolSearchPath += StringUtils::GetDirectoryName(ModulePath);
|
||||||
strcat_s(SymPath, nSymPathLen, szTemp);
|
symbolSearchPath += ";";
|
||||||
strcat_s(SymPath, nSymPathLen, ";");
|
|
||||||
}
|
}
|
||||||
|
for (auto& path : SymbolsPath)
|
||||||
// Main module path
|
|
||||||
if (GetModuleFileNameA(nullptr, szTemp, nTempLen) > 0)
|
|
||||||
{
|
{
|
||||||
szTemp[nTempLen - 1] = 0;
|
symbolSearchPath += path;
|
||||||
for (char* p = (szTemp + strlen(szTemp) - 1); p >= szTemp; --p)
|
symbolSearchPath += ";";
|
||||||
{
|
|
||||||
// Locate the rightmost path separator
|
|
||||||
if ((*p == '\\') || (*p == '/') || (*p == ':'))
|
|
||||||
{
|
|
||||||
*p = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (strlen(szTemp) > 0)
|
|
||||||
{
|
|
||||||
strcat_s(SymPath, nSymPathLen, szTemp);
|
|
||||||
strcat_s(SymPath, nSymPathLen, ";");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
String _NT_SYMBOL_PATH;
|
||||||
// System symbols paths
|
if (!Platform::GetEnvironmentVariable(TEXT("_NT_SYMBOL_PATH"), _NT_SYMBOL_PATH))
|
||||||
if (GetEnvironmentVariableA("_NT_SYMBOL_PATH", szTemp, nTempLen) > 0)
|
|
||||||
{
|
{
|
||||||
szTemp[nTempLen - 1] = 0;
|
symbolSearchPath += _NT_SYMBOL_PATH;
|
||||||
strcat_s(SymPath, nSymPathLen, szTemp);
|
symbolSearchPath += ";";
|
||||||
strcat_s(SymPath, nSymPathLen, ";");
|
|
||||||
}
|
}
|
||||||
if (GetEnvironmentVariableA("_NT_ALTERNATE_SYMBOL_PATH", szTemp, nTempLen) > 0)
|
symbolSearchPath += Platform::GetWorkingDirectory();
|
||||||
{
|
symbolSearchPath += ";";
|
||||||
szTemp[nTempLen - 1] = 0;
|
|
||||||
strcat_s(SymPath, nSymPathLen, szTemp);
|
|
||||||
strcat_s(SymPath, nSymPathLen, ";");
|
|
||||||
}
|
|
||||||
if (GetEnvironmentVariableA("SYSTEMROOT", szTemp, nTempLen) > 0)
|
|
||||||
{
|
|
||||||
szTemp[nTempLen - 1] = 0;
|
|
||||||
strcat_s(SymPath, nSymPathLen, szTemp);
|
|
||||||
strcat_s(SymPath, nSymPathLen, ";");
|
|
||||||
|
|
||||||
strcat_s(szTemp, nTempLen, "\\system32");
|
|
||||||
strcat_s(SymPath, nSymPathLen, szTemp);
|
|
||||||
strcat_s(SymPath, nSymPathLen, ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
SymInitialize(process, SymPath, FALSE);
|
|
||||||
|
|
||||||
DWORD options = SymGetOptions();
|
DWORD options = SymGetOptions();
|
||||||
options |= SYMOPT_LOAD_LINES;
|
options |= SYMOPT_LOAD_LINES;
|
||||||
options |= SYMOPT_FAIL_CRITICAL_ERRORS;
|
options |= SYMOPT_FAIL_CRITICAL_ERRORS;
|
||||||
|
options |= SYMOPT_DEFERRED_LOADS;
|
||||||
|
options |= SYMOPT_EXACT_SYMBOLS;
|
||||||
SymSetOptions(options);
|
SymSetOptions(options);
|
||||||
|
|
||||||
|
SymInitializeW(process, *symbolSearchPath, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load modules
|
// Refresh modules if needed
|
||||||
if (SymModulesDirty)
|
if (SymModulesDirty)
|
||||||
{
|
{
|
||||||
SymModulesDirty = false;
|
SymModulesDirty = false;
|
||||||
GetModuleListPSAPI(process);
|
SymRefreshModuleList(process);
|
||||||
}
|
}
|
||||||
SymRefreshModuleList(process);
|
|
||||||
|
|
||||||
// Capture the context if missing
|
// Capture the context if missing
|
||||||
/*EXCEPTION_POINTERS exceptionPointers;
|
/*EXCEPTION_POINTERS exceptionPointers;
|
||||||
|
|||||||
Reference in New Issue
Block a user