| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "CommonCorePch.h"
- #ifdef DBGHELP_SYMBOL_MANAGER
- #include "Core/DbgHelpSymbolManager.h"
- // Initialization order
- // AB AutoSystemInfo
- // AD PerfCounter
- // AE PerfCounterSet
- // AM Output/Configuration
- // AN MemProtectHeap
- // AP DbgHelpSymbolManager
- // AQ CFGLogger
- // AR LeakReport
- // AS JavascriptDispatch/RecyclerObjectDumper
- // AT HeapAllocator/RecyclerHeuristic
- // AU RecyclerWriteBarrierManager
- #pragma warning(disable:4075) // initializers put in unrecognized initialization area on purpose
- #pragma init_seg(".CRT$XCAP")
- DbgHelpSymbolManager DbgHelpSymbolManager::Instance;
- void
- DbgHelpSymbolManager::Initialize()
- {
- char16 *wszSearchPath = nullptr;
- char16 *wszModuleDrive = nullptr;
- char16 *wszModuleDir = nullptr;
- char16 *wszOldSearchPath = nullptr;
- char16 *wszNewSearchPath = nullptr;
- char16 *wszModuleName = nullptr;
- char16 const *wszModule = nullptr;
- const size_t ceModuleName = _MAX_PATH;
- const size_t ceOldSearchPath = 32767;
- const size_t ceNewSearchPath = ceOldSearchPath + _MAX_PATH + 1;
- if (isInitialized)
- {
- return;
- }
- AutoCriticalSection autocs(&cs);
- if (isInitialized)
- {
- goto end;
- }
- isInitialized = true;
- hProcess = GetCurrentProcess();
- // Let's make sure the directory where chakra.dll is, is on the symbol path.
- wszModule = AutoSystemInfo::GetJscriptDllFileName();
- wszModuleName = NoCheckHeapNewArray(char16, ceModuleName);
- if (wszModuleName == nullptr)
- {
- goto end;
- }
- if (wcscmp(wszModule, _u("")) == 0)
- {
- if (PlatformAgnostic::SystemInfo::GetBinaryLocation(wszModuleName, static_cast<DWORD>(ceModuleName)))
- {
- wszModule = wszModuleName;
- }
- else
- {
- wszModule = nullptr;
- }
- }
- if (wszModule != nullptr)
- {
- wszModuleDrive = NoCheckHeapNewArray(char16, _MAX_DRIVE);
- if (wszModuleDrive == nullptr)
- {
- goto end;
- }
- wszModuleDir = NoCheckHeapNewArray(char16, _MAX_DIR);
- if (wszModuleDir == nullptr)
- {
- goto end;
- }
- _wsplitpath_s(wszModule, wszModuleDrive, _MAX_DRIVE, wszModuleDir, _MAX_DIR, NULL, 0, NULL, 0);
- _wmakepath_s(wszModuleName, ceModuleName, wszModuleDrive, wszModuleDir, NULL, NULL);
- wszOldSearchPath = NoCheckHeapNewArray(char16, ceOldSearchPath);
- if (wszOldSearchPath == nullptr)
- {
- goto end;
- }
- wszNewSearchPath = NoCheckHeapNewArray(char16, ceNewSearchPath);
- if (wszNewSearchPath == nullptr)
- {
- goto end;
- }
- if (GetEnvironmentVariable(_u("_NT_SYMBOL_PATH"), wszOldSearchPath, static_cast<DWORD>(ceOldSearchPath)) != 0)
- {
- swprintf_s(wszNewSearchPath, ceNewSearchPath, _u("%s;%s"), wszOldSearchPath, wszModuleName);
- wszSearchPath = wszNewSearchPath;
- }
- else
- {
- wszSearchPath = wszModuleName;
- }
- }
- hDbgHelpModule = LoadLibraryEx(_u("dbghelp.dll"), NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
- if (hDbgHelpModule == nullptr)
- {
- goto end;
- }
- {
- typedef BOOL(__stdcall *PfnSymInitialize)(HANDLE, PCWSTR, BOOL);
- PfnSymInitialize pfnSymInitialize = (PfnSymInitialize)GetProcAddress(hDbgHelpModule, "SymInitializeW");
- if (pfnSymInitialize)
- {
- pfnSymInitialize(hProcess, wszSearchPath, TRUE);
- pfnSymFromAddrW = (PfnSymFromAddrW)GetProcAddress(hDbgHelpModule, "SymFromAddrW");
- pfnSymGetLineFromAddr64W = (PfnSymGetLineFromAddr64W)GetProcAddress(hDbgHelpModule, "SymGetLineFromAddrW64");
- // load line information
- typedef DWORD(__stdcall *PfnSymGetOptions)();
- typedef VOID(__stdcall *PfnSymSetOptions)(DWORD);
- PfnSymGetOptions pfnSymGetOptions = (PfnSymGetOptions)GetProcAddress(hDbgHelpModule, "SymGetOptions");
- PfnSymSetOptions pfnSymSetOptions = (PfnSymSetOptions)GetProcAddress(hDbgHelpModule, "SymSetOptions");
- DWORD options = pfnSymGetOptions();
- options |= SYMOPT_LOAD_LINES;
- pfnSymSetOptions(options);
- }
- }
- end:
- if (wszModuleName != nullptr)
- {
- NoCheckHeapDeleteArray(ceModuleName, wszModuleName);
- wszModuleName = nullptr;
- }
- if (wszModuleDrive != nullptr)
- {
- NoCheckHeapDeleteArray(_MAX_DRIVE, wszModuleDrive);
- wszModuleDrive = nullptr;
- }
- if (wszModuleDir != nullptr)
- {
- NoCheckHeapDeleteArray(_MAX_DIR, wszModuleDir);
- wszModuleDir = nullptr;
- }
- if (wszOldSearchPath != nullptr)
- {
- NoCheckHeapDeleteArray(ceOldSearchPath, wszOldSearchPath);
- wszOldSearchPath = nullptr;
- }
- if (wszNewSearchPath != nullptr)
- {
- NoCheckHeapDeleteArray(ceNewSearchPath, wszNewSearchPath);
- wszNewSearchPath = nullptr;
- }
- }
- DbgHelpSymbolManager::~DbgHelpSymbolManager()
- {
- if (hDbgHelpModule)
- {
- typedef BOOL(__stdcall *PfnSymCleanup)(HANDLE);
- PfnSymCleanup pfnSymCleanup = (PfnSymCleanup)GetProcAddress(hDbgHelpModule, "SymCleanup");
- if (pfnSymCleanup)
- {
- pfnSymCleanup(hProcess);
- }
- FreeLibrary(hDbgHelpModule);
- }
- }
- BOOL
- DbgHelpSymbolManager::SymFromAddr(PVOID address, DWORD64 * dwDisplacement, PSYMBOL_INFO pSymbol)
- {
- if (Instance.pfnSymFromAddrW)
- {
- return Instance.pfnSymFromAddrW(Instance.hProcess, (DWORD64)address, dwDisplacement, pSymbol);
- }
- return FALSE;
- }
- BOOL
- DbgHelpSymbolManager::SymGetLineFromAddr64(_In_ PVOID address, _Out_ PDWORD pdwDisplacement, _Out_ PIMAGEHLP_LINEW64 pLine)
- {
- if (pdwDisplacement != nullptr)
- {
- *pdwDisplacement = 0;
- }
- if (pLine != nullptr)
- {
- ZeroMemory(pLine, sizeof(IMAGEHLP_LINEW64));
- pLine->SizeOfStruct = sizeof(IMAGEHLP_LINE64);
- }
- if (Instance.pfnSymGetLineFromAddr64W)
- {
- return Instance.pfnSymGetLineFromAddr64W(Instance.hProcess, (DWORD64)address, pdwDisplacement, pLine);
- }
- return FALSE;
- }
- size_t DbgHelpSymbolManager::PrintSymbol(PVOID address)
- {
- size_t retValue = 0;
- DWORD64 dwDisplacement = 0;
- char buffer[sizeof(SYMBOL_INFO)+MAX_SYM_NAME * sizeof(TCHAR)];
- PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
- pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
- pSymbol->MaxNameLen = MAX_SYM_NAME;
- IMAGEHLP_LINE64 lineInfo;
- lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
- if (DbgHelpSymbolManager::SymFromAddr(address, &dwDisplacement, pSymbol))
- {
- DWORD dwDisplacementDWord = static_cast<DWORD>(dwDisplacement);
- if (DbgHelpSymbolManager::SymGetLineFromAddr64(address, &dwDisplacementDWord, &lineInfo))
- {
- retValue += Output::Print(_u("0x%p %s+0x%llx (%s:%d)"), address, pSymbol->Name, dwDisplacement, lineInfo.FileName, lineInfo.LineNumber);
- }
- else
- {
- // SymGetLineFromAddr64 failed
- retValue += Output::Print(_u("0x%p %s+0x%llx"), address, pSymbol->Name, dwDisplacement);
- }
- }
- else
- {
- // SymFromAddr failed
- retValue += Output::Print(_u("0x%p"), address);
- }
- return retValue;
- }
- #endif
|