summaryrefslogtreecommitdiff
path: root/src/ToolBox/SOS
diff options
context:
space:
mode:
authorEvgeny Pavlov <lucenticus@gmail.com>2016-06-15 19:23:30 +0300
committerMike McLaughlin <mikem@microsoft.com>2016-06-15 09:23:30 -0700
commit859307b4787bbacbe28d2efe1d54c49177525562 (patch)
tree0a255a882ffd1689cc34f1e0146dae3c46e4ceb6 /src/ToolBox/SOS
parent488c377745cd2cbdfac711d2199dfeefeb24c5f1 (diff)
downloadcoreclr-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.txt8
-rw-r--r--src/ToolBox/SOS/Strike/strike.cpp33
-rw-r--r--src/ToolBox/SOS/Strike/util.cpp136
-rw-r--r--src/ToolBox/SOS/Strike/util.h27
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,