Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

[SOS][Linux] Support of reading local variables from portable PDB #5897

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/ToolBox/SOS/Strike/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,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/ToolBox/SOS/Strike/strike.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11562,26 +11562,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/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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style comment: I noticed that there are a few different styles all in use in this area. Sometimes there are braces around single-statement 'if' blocks, and sometimes there aren't. Brace position should also be consistent with the surrounding code (I think before your changes, most/all of the file used Allman style).

{
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/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