Skip to content

Commit

Permalink
[SOS][Linux] Support of reading local variables from portable PDB (do…
Browse files Browse the repository at this point in the history
…tnet/coreclr#5897)

* Initial support of reading local variables from portable pdb using System.Diagnostics.Debug.SymbolReader.dll

* Use SysAllocString and SysFreeString for memory management

* Fix coding style after review


Commit migrated from dotnet/coreclr@b5ab114
  • Loading branch information
lucenticus authored and adityamandaleeka committed Jun 24, 2016
1 parent 6b32018 commit 5233d54
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 25 deletions.
1 change: 1 addition & 0 deletions src/coreclr/src/ToolBox/SOS/Strike/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ else(WIN32)
dbgutil
# share the PAL in the dac module
mscordaccore
palrt
)

set(DEF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/sos_unixexports.src)
Expand Down
4 changes: 0 additions & 4 deletions src/coreclr/src/ToolBox/SOS/Strike/strike.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11561,26 +11561,22 @@ class ClrStackImplWithICorDebug
IfFailRet(pLocalsEnum->GetCount(&cLocals));
if (cLocals > 0 && bLocals)
{
#ifndef FEATURE_PAL
bool symbolsAvailable = false;
SymbolReader symReader;
if(SUCCEEDED(symReader.LoadSymbols(pMD, pModule)))
symbolsAvailable = true;
#endif
ExtOut("\nLOCALS:\n");
for (ULONG i=0; i < cLocals; i++)
{
ULONG paramNameLen = 0;
WCHAR paramName[mdNameLen] = W("\0");

ToRelease<ICorDebugValue> pValue;
#ifndef FEATURE_PAL
if(symbolsAvailable)
{
Status = symReader.GetNamedLocalVariable(pILFrame, i, paramName, mdNameLen, &pValue);
}
else
#endif
{
ULONG cArgsFetched;
Status = pLocalsEnum->Next(1, &pValue, &cArgsFetched);
Expand Down
87 changes: 66 additions & 21 deletions src/coreclr/src/ToolBox/SOS/Strike/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ PIMAGEHLP_SYMBOL sym = (PIMAGEHLP_SYMBOL) symBuffer;
void *SymbolReader::coreclrLib;
ResolveSequencePointDelegate SymbolReader::resolveSequencePointDelegate;
LoadSymbolsForModuleDelegate SymbolReader::loadSymbolsForModuleDelegate;
GetLocalVariableName SymbolReader::getLocalVariableNameDelegate;
#endif // !FEATURE_PAL

const char * const CorElementTypeName[ELEMENT_TYPE_MAX]=
Expand Down Expand Up @@ -6208,16 +6209,19 @@ HRESULT SymbolReader::LoadSymbols(IMetaDataImport * pMD, ICorDebugModule * pModu
}

#ifdef FEATURE_PAL
bool SymbolReader::SymbolReaderDllExists() {
bool SymbolReader::SymbolReaderDllExists()
{
struct stat sb;
std::string SymbolReaderDll(SymbolReaderDllName);
SymbolReaderDll += ".dll";
if (stat(SymbolReaderDll.c_str(), &sb) == -1) {
if (stat(SymbolReaderDll.c_str(), &sb) == -1)
{
return false;
}
return true;
}
HRESULT SymbolReader::LoadCoreCLR() {
HRESULT SymbolReader::LoadCoreCLR()
{
HRESULT Status = S_OK;

std::string absolutePath, coreClrPath;
Expand Down Expand Up @@ -6259,7 +6263,8 @@ HRESULT SymbolReader::LoadCoreCLR() {
"UseLatestBehaviorWhenTFMNotSpecified"};
std::string entryPointExecutablePath;

if (!GetEntrypointExecutableAbsolutePath(entryPointExecutablePath)) {
if (!GetEntrypointExecutableAbsolutePath(entryPointExecutablePath))
{
perror("Could not get full path to current executable");
return E_FAIL;
}
Expand All @@ -6268,22 +6273,24 @@ HRESULT SymbolReader::LoadCoreCLR() {
initializeCoreCLR(entryPointExecutablePath.c_str(), "soscorerun",
sizeof(propertyKeys) / sizeof(propertyKeys[0]),
propertyKeys, propertyValues, &hostHandle, &domainId);
if (Status != S_OK) {
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,
IfFailRet(CreateDelegate(hostHandle, domainId, SymbolReaderDllName,
SymbolReaderClassName, "ResolveSequencePoint",
(void **)&resolveSequencePointDelegate);
IfFailRet(Status);
Status = CreateDelegate(hostHandle, domainId, SymbolReaderDllName,
(void **)&resolveSequencePointDelegate));
IfFailRet(CreateDelegate(hostHandle, domainId, SymbolReaderDllName,
SymbolReaderClassName, "LoadSymbolsForModule",
(void **)&loadSymbolsForModuleDelegate);
IfFailRet(Status);
(void **)&loadSymbolsForModuleDelegate));
IfFailRet(CreateDelegate(hostHandle, domainId, SymbolReaderDllName,
SymbolReaderClassName, "GetLocalVariableName",
(void **)&getLocalVariableNameDelegate));
return Status;
}
#endif //FEATURE_PAL
Expand Down Expand Up @@ -6357,36 +6364,69 @@ HRESULT SymbolReader::LoadSymbols(IMetaDataImport * pMD, ULONG64 baseAddress, __
}
return Status;
#else
if (loadSymbolsForModuleDelegate == nullptr) {
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);
m_szModuleName, mdNameLen, NULL, NULL);
return !loadSymbolsForModuleDelegate(m_szModuleName);
#endif // FEATURE_PAL
}

HRESULT SymbolReader::GetNamedLocalVariable(ISymUnmanagedScope * pScope, ICorDebugILFrame * pILFrame, mdMethodDef methodToken, ULONG localIndex, __inout_ecount(paramNameLen) WCHAR* paramName, ULONG paramNameLen, ICorDebugValue** ppValue)
{
HRESULT Status = S_OK;
#ifdef FEATURE_PAL
if (getLocalVariableNameDelegate == nullptr)
{
Status = LoadCoreCLR();
}
if (Status != S_OK)
{
return Status;
}
BSTR wszParamName = SysAllocStringLen(0, mdNameLen);
if (wszParamName == NULL)
{
return E_OUTOFMEMORY;
}
int ret = getLocalVariableNameDelegate(m_szModuleName, methodToken,
localIndex, &wszParamName);
if (ret)
{
wcscpy_s(paramName, _wcslen(wszParamName) + 1, wszParamName);
paramNameLen = _wcslen(paramName);
SysFreeString(wszParamName);

if (SUCCEEDED(pILFrame->GetLocalVariable(localIndex, ppValue)) && (*ppValue != NULL))
{
return S_OK;
}
else
{
*ppValue = NULL;
return E_FAIL;
}
}
SysFreeString(wszParamName);
return E_FAIL;

#else
if(pScope == NULL)
{
#ifndef FEATURE_PAL
ToRelease<ISymUnmanagedMethod> pSymMethod;
IfFailRet(m_pSymReader->GetMethod(methodToken, &pSymMethod));

ToRelease<ISymUnmanagedScope> pScope;
IfFailRet(pSymMethod->GetRootScope(&pScope));

return GetNamedLocalVariable(pScope, pILFrame, methodToken, localIndex, paramName, paramNameLen, ppValue);
#else
return E_FAIL;
#endif // FEATURE_PAL
}
else
{
Expand All @@ -6404,7 +6444,7 @@ HRESULT SymbolReader::GetNamedLocalVariable(ISymUnmanagedScope * pScope, ICorDeb
if(varIndexInMethod != localIndex)
continue;

ULONG32 nameLen = 0;
ULONG32 nameLen = 0;
if(FAILED(pLocals[i]->GetName(paramNameLen, &nameLen, paramName)))
swprintf_s(paramName, paramNameLen, W("local_%d\0"), localIndex);

Expand Down Expand Up @@ -6440,7 +6480,9 @@ HRESULT SymbolReader::GetNamedLocalVariable(ISymUnmanagedScope * pScope, ICorDeb
for(ULONG j = 0; j < numChildren; j++) pChildren[j]->Release();

}

return E_FAIL;
#endif // FEATURE_PAL
}

HRESULT SymbolReader::GetNamedLocalVariable(ICorDebugFrame * pFrame, ULONG localIndex, __inout_ecount(paramNameLen) WCHAR* paramName, ULONG paramNameLen, ICorDebugValue** ppValue)
Expand Down Expand Up @@ -6529,11 +6571,14 @@ HRESULT SymbolReader::ResolveSequencePoint(__in_z WCHAR* pFilename, ULONG32 line
}
return E_FAIL;
#else
if (loadSymbolsForModuleDelegate == nullptr) {
if (loadSymbolsForModuleDelegate == nullptr)
{
Status = LoadCoreCLR();
}
if (Status != S_OK)
{
return Status;
}

char szName[mdNameLen];
WideCharToMultiByte(CP_ACP, 0, pFilename, (int) (_wcslen(pFilename) + 1),
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/src/ToolBox/SOS/Strike/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -2358,6 +2358,7 @@ class PERvaMemoryReader : IDiaReadExeAtRVACallback
#ifdef FEATURE_PAL
typedef int (*ResolveSequencePointDelegate)(const char*, const char*, unsigned int, unsigned int*, unsigned int*);
typedef int (*LoadSymbolsForModuleDelegate)(const char*);
typedef int (*GetLocalVariableName)(const char*, int, int, BSTR*);
static const char *SymbolReaderDllName = "System.Diagnostics.Debug.SymbolReader";
static const char *SymbolReaderClassName = "System.Diagnostics.Debug.SymbolReader.SymbolReader";
#endif //FEATURE_PAL
Expand All @@ -2368,8 +2369,10 @@ class SymbolReader
ISymUnmanagedReader* m_pSymReader;
#ifdef FEATURE_PAL
static void *coreclrLib;
char m_szModuleName[mdNameLen];
static ResolveSequencePointDelegate resolveSequencePointDelegate;
static LoadSymbolsForModuleDelegate loadSymbolsForModuleDelegate;
static GetLocalVariableName getLocalVariableNameDelegate;
#endif

private:
Expand Down

0 comments on commit 5233d54

Please sign in to comment.