diff options
author | Evgeny Pavlov <lucenticus@gmail.com> | 2016-06-15 19:23:30 +0300 |
---|---|---|
committer | Mike McLaughlin <mikem@microsoft.com> | 2016-06-15 09:23:30 -0700 |
commit | 859307b4787bbacbe28d2efe1d54c49177525562 (patch) | |
tree | 0a255a882ffd1689cc34f1e0146dae3c46e4ceb6 /src/ToolBox/SOS | |
parent | 488c377745cd2cbdfac711d2199dfeefeb24c5f1 (diff) | |
download | coreclr-859307b4787bbacbe28d2efe1d54c49177525562.tar.gz coreclr-859307b4787bbacbe28d2efe1d54c49177525562.tar.bz2 coreclr-859307b4787bbacbe28d2efe1d54c49177525562.zip |
Initial support of breakpoint setting by source file + line on Linux using portable pdb reader (#5688)
* Initial support of breakpoint setting by source + line on Linux
* Fix macro redefinition error in OSX build
* Fix after review from Mike McLaughlin
Diffstat (limited to 'src/ToolBox/SOS')
-rw-r--r-- | src/ToolBox/SOS/Strike/CMakeLists.txt | 8 | ||||
-rw-r--r-- | src/ToolBox/SOS/Strike/strike.cpp | 33 | ||||
-rw-r--r-- | src/ToolBox/SOS/Strike/util.cpp | 136 | ||||
-rw-r--r-- | src/ToolBox/SOS/Strike/util.h | 27 |
4 files changed, 177 insertions, 27 deletions
diff --git a/src/ToolBox/SOS/Strike/CMakeLists.txt b/src/ToolBox/SOS/Strike/CMakeLists.txt index 5d12a0c329..c474574a08 100644 --- a/src/ToolBox/SOS/Strike/CMakeLists.txt +++ b/src/ToolBox/SOS/Strike/CMakeLists.txt @@ -44,6 +44,8 @@ remove_definitions(-D_UNICODE) include_directories(BEFORE ${VM_DIR}) include_directories(${CLR_DIR}/src/gcdump) include_directories(${CLR_DIR}/src/debug/shim) +include_directories(${CLR_DIR}/src/coreclr/hosts/unixcoreruncommon) +include_directories(${CLR_DIR}/src/coreclr/hosts/inc) if(WIN32) include_directories(inc) @@ -123,6 +125,12 @@ else(WIN32) sos.cpp util.cpp ) + if(CLR_CMAKE_PLATFORM_DARWIN) + set(SOS_SOURCES + ${SOS_SOURCES} + ../../../coreclr/hosts/unixcoreruncommon/coreruncommon.cpp + ) + endif(CLR_CMAKE_PLATFORM_DARWIN) set(SOS_LIBRARY corguids diff --git a/src/ToolBox/SOS/Strike/strike.cpp b/src/ToolBox/SOS/Strike/strike.cpp index e89043d17f..ceffb8af51 100644 --- a/src/ToolBox/SOS/Strike/strike.cpp +++ b/src/ToolBox/SOS/Strike/strike.cpp @@ -6368,7 +6368,6 @@ public: HRESULT LoadSymbolsForModule(TADDR mod, SymbolReader* pSymbolReader) { -#ifndef FEATURE_PAL HRESULT Status = S_OK; ToRelease<IXCLRDataModule> module; IfFailRet(g_sos->GetModule(mod, &module)); @@ -6392,6 +6391,8 @@ public: pModuleFilename = pSlash+1; pSlash = _wcschr(pModuleFilename, DIRECTORY_SEPARATOR_CHAR_W); } + return S_OK; +#ifndef FEATURE_PAL ImageInfo ii; if(FAILED(Status = GetClrModuleImages(module, CLRDATA_MODULE_PE_FILE, &ii))) @@ -6406,8 +6407,13 @@ public: ExtOut("SOS warning: No symbols for module %S, source line breakpoints in this module will not bind hr=0x%x\n", wszNameBuffer, Status); return S_FALSE; // not finding symbols is a typical case } +#else + if(FAILED(Status = pSymbolReader->LoadSymbols(pMDImport, 0, pModuleFilename, FALSE))) + { + return S_FALSE; + } + return Status; #endif // FEATURE_PAL - return S_OK; } HRESULT ResolvePendingNonModuleBoundBreakpoint(__in_z WCHAR* pFilename, DWORD lineNumber, TADDR mod, SymbolReader* pSymbolReader) @@ -6418,7 +6424,7 @@ public: mdMethodDef methodDef; ULONG32 ilOffset; - if(FAILED(Status = pSymbolReader->ResolveSequencePoint(pFilename, lineNumber, &methodDef, &ilOffset))) + if(FAILED(Status = pSymbolReader->ResolveSequencePoint(pFilename, lineNumber, mod, &methodDef, &ilOffset))) { return S_FALSE; // not binding in a module is typical } @@ -7033,7 +7039,8 @@ DECLARE_API(bpmd) ExtOut("!bpmd is not supported on a dump file.\n"); return Status; } - + + // We keep a list of managed breakpoints the user wants to set, and display pending bps // bpmd. If you call bpmd <module name> <method> we will set or update an existing bp. // bpmd acts as a feeder of breakpoints to bp when the time is right. @@ -7110,9 +7117,13 @@ DECLARE_API(bpmd) // did we get dll and type name or file:line#? Search for a colon in the first arg // to see if it is in fact a file:line# CHAR* pColon = strchr(DllName.data, ':'); + if (FAILED(g_ExtSymbols->GetModuleByModuleName(MAIN_CLR_DLL_NAME_A, 0, NULL, NULL))) { + ExtOut("File name:Line number not supported\n"); + fBadParam = true; + } + if(NULL != pColon) { -#ifndef FEATURE_PAL fIsFilename = true; *pColon = '\0'; pColon++; @@ -7127,9 +7138,13 @@ DECLARE_API(bpmd) fBadParam = true; } if(nArg != 1) fBadParam = 1; -#else - ExtOut("File name:Line number not supported\n"); - fBadParam = true; +#ifdef FEATURE_PAL + if (!SymbolReader::SymbolReaderDllExists()) + { + ExtOut("Can't find dll for symbol reader."); + ExtOut("File name:Line number not supported\n"); + fBadParam = true; + } #endif // FEATURE_PAL } } @@ -7245,7 +7260,7 @@ DECLARE_API(bpmd) // if we have symbols then get the function name so we can lookup the MethodDescs mdMethodDef methodDefToken; ULONG32 ilOffset; - if(SUCCEEDED(symbolReader.ResolveSequencePoint(Filename, lineNumber, &methodDefToken, &ilOffset))) + if(SUCCEEDED(symbolReader.ResolveSequencePoint(Filename, lineNumber, moduleList[iModule], &methodDefToken, &ilOffset))) { ToRelease<IXCLRDataMethodDefinition> pMethodDef = NULL; if (SUCCEEDED(ModDef->GetMethodDefinitionByToken(methodDefToken, &pMethodDef))) diff --git a/src/ToolBox/SOS/Strike/util.cpp b/src/ToolBox/SOS/Strike/util.cpp index fc728ade26..565b47d208 100644 --- a/src/ToolBox/SOS/Strike/util.cpp +++ b/src/ToolBox/SOS/Strike/util.cpp @@ -42,6 +42,16 @@ #define SYM_BUFFER_SIZE (sizeof(IMAGEHLP_SYMBOL) + MAX_SYMBOL_LEN) char symBuffer[SYM_BUFFER_SIZE]; PIMAGEHLP_SYMBOL sym = (PIMAGEHLP_SYMBOL) symBuffer; +#else + +#include <sys/stat.h> +#include <coreruncommon.h> +#include <dlfcn.h> +#include <coreclrhost.h> + +void *SymbolReader::coreclrLib; +ResolveSequencePointDelegate SymbolReader::resolveSequencePointDelegate; +LoadSymbolsForModuleDelegate SymbolReader::loadSymbolsForModuleDelegate; #endif // !FEATURE_PAL const char * const CorElementTypeName[ELEMENT_TYPE_MAX]= @@ -2716,7 +2726,7 @@ DWORD_PTR *ModuleFromName(__in_opt LPSTR mName, int *numModule) ReportOOM(); return NULL; } - + WCHAR StringData[MAX_PATH_FNAME]; char fileName[sizeof(StringData)/2]; @@ -6170,7 +6180,6 @@ HRESULT __stdcall PERvaMemoryReader::ReadExecutableAtRVA(DWORD relativeVirtualAd HRESULT SymbolReader::LoadSymbols(IMetaDataImport * pMD, ICorDebugModule * pModule) { -#ifndef FEATURE_PAL HRESULT Status = S_OK; if(m_pSymReader != NULL) return S_OK; @@ -6196,15 +6205,93 @@ HRESULT SymbolReader::LoadSymbols(IMetaDataImport * pMD, ICorDebugModule * pModu IfFailRet(pModule->GetName(_countof(moduleName), &len, moduleName)); return LoadSymbols(pMD, baseAddress, moduleName, isInMemory); -#else - return E_FAIL; -#endif // FEATURE_PAL } +#ifdef FEATURE_PAL +bool SymbolReader::SymbolReaderDllExists() { + struct stat sb; + std::string SymbolReaderDll(SymbolReaderDllName); + SymbolReaderDll += ".dll"; + if (stat(SymbolReaderDll.c_str(), &sb) == -1) { + return false; + } + return true; +} +HRESULT SymbolReader::LoadCoreCLR() { + HRESULT Status = S_OK; + + std::string absolutePath, coreClrPath; + absolutePath = g_ExtServices->GetCoreClrDirectory(); + GetDirectory(absolutePath.c_str(), coreClrPath); + coreClrPath.append("/"); + coreClrPath.append(coreClrDll); + + coreclrLib = dlopen(coreClrPath.c_str(), RTLD_NOW | RTLD_LOCAL); + if (coreclrLib == nullptr) + { + fprintf(stderr, "Error: Fail to load %s\n", coreClrPath.c_str()); + return E_FAIL; + } + void *hostHandle; + unsigned int domainId; + coreclr_initialize_ptr initializeCoreCLR = + (coreclr_initialize_ptr)dlsym(coreclrLib, "coreclr_initialize"); + + // FiXME: We should shutdown coreclr when it is not needed + coreclr_shutdown_ptr shutdownCoreCLR = + (coreclr_shutdown_ptr)dlsym(coreclrLib, "coreclr_shutdown"); + std::string tpaList; + AddFilesFromDirectoryToTpaList(absolutePath.c_str(), tpaList); + + const char *propertyKeys[] = { + "TRUSTED_PLATFORM_ASSEMBLIES", "APP_PATHS", "APP_NI_PATHS", + "NATIVE_DLL_SEARCH_DIRECTORIES", "AppDomainCompatSwitch"}; + + const char *propertyValues[] = {// TRUSTED_PLATFORM_ASSEMBLIES + tpaList.c_str(), + // APP_PATHS + absolutePath.c_str(), + // APP_NI_PATHS + absolutePath.c_str(), + // NATIVE_DLL_SEARCH_DIRECTORIES + absolutePath.c_str(), + // AppDomainCompatSwitch + "UseLatestBehaviorWhenTFMNotSpecified"}; + std::string entryPointExecutablePath; + + if (!GetEntrypointExecutableAbsolutePath(entryPointExecutablePath)) { + perror("Could not get full path to current executable"); + return E_FAIL; + } + + Status = + initializeCoreCLR(entryPointExecutablePath.c_str(), "soscorerun", + sizeof(propertyKeys) / sizeof(propertyKeys[0]), + propertyKeys, propertyValues, &hostHandle, &domainId); + if (Status != S_OK) { + fprintf(stderr, "Error: Fail to initialize CoreCLR\n"); + return Status; + } + + coreclr_create_delegate_ptr CreateDelegate = + (coreclr_create_delegate_ptr)dlsym(coreclrLib, + "coreclr_create_delegate"); + Status = CreateDelegate(hostHandle, domainId, SymbolReaderDllName, + SymbolReaderClassName, "ResolveSequencePoint", + (void **)&resolveSequencePointDelegate); + IfFailRet(Status); + Status = CreateDelegate(hostHandle, domainId, SymbolReaderDllName, + SymbolReaderClassName, "LoadSymbolsForModule", + (void **)&loadSymbolsForModuleDelegate); + IfFailRet(Status); + return Status; +} +#endif //FEATURE_PAL HRESULT SymbolReader::LoadSymbols(IMetaDataImport * pMD, ULONG64 baseAddress, __in_z WCHAR* pModuleName, BOOL isInMemory) { + HRESULT Status = S_OK; + #ifndef FEATURE_PAL - HRESULT Status = S_OK; if(m_pSymReader != NULL) return S_OK; @@ -6270,7 +6357,16 @@ HRESULT SymbolReader::LoadSymbols(IMetaDataImport * pMD, ULONG64 baseAddress, __ } return Status; #else - return E_FAIL; + if (loadSymbolsForModuleDelegate == nullptr) { + Status = LoadCoreCLR(); + } + if (Status != S_OK) + return Status; + + char szName[mdNameLen]; + WideCharToMultiByte(CP_ACP, 0, pModuleName, (int) (_wcslen(pModuleName) + 1), + szName, mdNameLen, NULL, NULL); + return !loadSymbolsForModuleDelegate(szName); #endif // FEATURE_PAL } @@ -6370,10 +6466,11 @@ HRESULT SymbolReader::GetNamedLocalVariable(ICorDebugFrame * pFrame, ULONG local return GetNamedLocalVariable(NULL, pILFrame, methodDef, localIndex, paramName, paramNameLen, ppValue); } -HRESULT SymbolReader::ResolveSequencePoint(__in_z WCHAR* pFilename, ULONG32 lineNumber, mdMethodDef* pToken, ULONG32* pIlOffset) +HRESULT SymbolReader::ResolveSequencePoint(__in_z WCHAR* pFilename, ULONG32 lineNumber, TADDR mod, mdMethodDef* pToken, ULONG32* pIlOffset) { -#ifndef FEATURE_PAL HRESULT Status = S_OK; + +#ifndef FEATURE_PAL ULONG32 cDocs = 0; ULONG32 cDocsNeeded = 0; ArrayHolder<ToRelease<ISymUnmanagedDocument>> pDocs = NULL; @@ -6430,8 +6527,27 @@ HRESULT SymbolReader::ResolveSequencePoint(__in_z WCHAR* pFilename, ULONG32 line } return S_OK; } -#endif // FEATURE_PAL return E_FAIL; +#else + if (loadSymbolsForModuleDelegate == nullptr) { + Status = LoadCoreCLR(); + } + if (Status != S_OK) + return Status; + + char szName[mdNameLen]; + WideCharToMultiByte(CP_ACP, 0, pFilename, (int) (_wcslen(pFilename) + 1), + szName, mdNameLen, NULL, NULL); + + WCHAR FileNameW[MAX_LONGPATH]; + char FileName[MAX_LONGPATH]; + FileNameForModule(mod, FileNameW); + + WideCharToMultiByte(CP_ACP, 0, FileNameW, (int) (_wcslen(FileNameW) + 1), FileName, MAX_LONGPATH, NULL, NULL); + Status = resolveSequencePointDelegate(FileName, szName, lineNumber, pToken, pIlOffset); + + return Status; +#endif // FEATURE_PAL } static void AddAssemblyName(WString& methodOutput, CLRDATA_ADDRESS mdesc) diff --git a/src/ToolBox/SOS/Strike/util.h b/src/ToolBox/SOS/Strike/util.h index 1c4e811a40..f1003bc658 100644 --- a/src/ToolBox/SOS/Strike/util.h +++ b/src/ToolBox/SOS/Strike/util.h @@ -2355,19 +2355,29 @@ private: #endif // !FEATURE_PAL +#ifdef FEATURE_PAL +typedef int (*ResolveSequencePointDelegate)(const char*, const char*, unsigned int, unsigned int*, unsigned int*); +typedef int (*LoadSymbolsForModuleDelegate)(const char*); +static const char *SymbolReaderDllName = "System.Diagnostics.Debug.SymbolReader"; +static const char *SymbolReaderClassName = "System.Diagnostics.Debug.SymbolReader.SymbolReader"; +#endif //FEATURE_PAL + class SymbolReader { private: -#ifndef FEATURE_PAL ISymUnmanagedReader* m_pSymReader; +#ifdef FEATURE_PAL + static void *coreclrLib; + static ResolveSequencePointDelegate resolveSequencePointDelegate; + static LoadSymbolsForModuleDelegate loadSymbolsForModuleDelegate; #endif private: HRESULT GetNamedLocalVariable(ISymUnmanagedScope * pScope, ICorDebugILFrame * pILFrame, mdMethodDef methodToken, ULONG localIndex, __inout_ecount(paramNameLen) WCHAR* paramName, ULONG paramNameLen, ICorDebugValue** ppValue); public: -#ifndef FEATURE_PAL - SymbolReader() : m_pSymReader (NULL) {} + SymbolReader() : m_pSymReader (NULL) { + } ~SymbolReader() { if(m_pSymReader != NULL) @@ -2376,17 +2386,18 @@ public: m_pSymReader = NULL; } } -#else - SymbolReader() {} - ~SymbolReader() {} -#endif +#ifdef FEATURE_PAL + static HRESULT LoadCoreCLR(); + static bool SymbolReaderDllExists(); +#endif //FEATURE_PAL HRESULT LoadSymbols(IMetaDataImport * pMD, ICorDebugModule * pModule); HRESULT LoadSymbols(IMetaDataImport * pMD, ULONG64 baseAddress, __in_z WCHAR* pModuleName, BOOL isInMemory); HRESULT GetNamedLocalVariable(ICorDebugFrame * pFrame, ULONG localIndex, __inout_ecount(paramNameLen) WCHAR* paramName, ULONG paramNameLen, ICorDebugValue** ppValue); - HRESULT SymbolReader::ResolveSequencePoint(__in_z WCHAR* pFilename, ULONG32 lineNumber, mdMethodDef* pToken, ULONG32* pIlOffset); + HRESULT SymbolReader::ResolveSequencePoint(__in_z WCHAR* pFilename, ULONG32 lineNumber, TADDR mod, mdMethodDef* pToken, ULONG32* pIlOffset); }; + HRESULT GetLineByOffset( ___in ULONG64 IP, |