[~] hierarchical symbol print

git-svn-id: https://pykd.svn.codeplex.com/svn@69954 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\EreTIk_cp 2011-09-22 14:38:42 +00:00 committed by Mikhail I. Izmestev
parent 6091868478
commit 972236f451
3 changed files with 129 additions and 35 deletions

View File

@ -227,17 +227,18 @@ ULONG Symbol::getLocType()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getOffset() LONG Symbol::getOffset()
{ {
return callSymbol(get_offset); return callSymbol(get_offset);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Symbol::getValueImpl(VARIANT &vtValue) void Symbol::getValueImpl(IDiaSymbol *_symbol, VARIANT &vtValue)
{ {
throwIfNull(__FUNCTION__); if (!_symbol)
throw Exception(std::string(__FUNCTION__) + " failed, DIA object is not initialized");
HRESULT hres = m_symbol->get_value(&vtValue); HRESULT hres = _symbol->get_value(&vtValue);
if (S_OK != hres) if (S_OK != hres)
throw Exception("Call IDiaSymbol::get_value", hres); throw Exception("Call IDiaSymbol::get_value", hres);
} }
@ -247,7 +248,7 @@ void Symbol::getValueImpl(VARIANT &vtValue)
python::object Symbol::getValue() python::object Symbol::getValue()
{ {
VARIANT vtValue = { VT_EMPTY }; VARIANT vtValue = { VT_EMPTY };
getValueImpl(vtValue); getValueImpl(m_symbol, vtValue);
switch (vtValue.vt) switch (vtValue.vt)
{ {
case VT_I1: case VT_I1:
@ -407,7 +408,10 @@ Symbol Symbol::getChildByIndex(ULONG _index)
throw Exception("Call IDiaEnumSymbols::get_Count", hres); throw Exception("Call IDiaEnumSymbols::get_Count", hres);
if (LONG(_index) >= count) if (LONG(_index) >= count)
throw Exception("Attempt to access non-existing element by index"); {
PyErr_SetString(PyExc_IndexError, "Index out of range");
boost::python::throw_error_already_set();
}
DiaSymbolPtr child; DiaSymbolPtr child;
hres = symbols->Item(_index, &child); hres = symbols->Item(_index, &child);
@ -420,47 +424,87 @@ Symbol Symbol::getChildByIndex(ULONG _index)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string Symbol::print() std::string Symbol::print()
{
return printImpl(m_symbol);
}
////////////////////////////////////////////////////////////////////////////////
std::string Symbol::printImpl(IDiaSymbol *_symbol, ULONG indent)
{ {
std::stringstream sstream; std::stringstream sstream;
if (m_symbol) for (ULONG i =0; i < indent; ++i)
sstream << " ";
if (indent >= 3)
{
sstream << "<...>";
return sstream.str();
}
if (_symbol)
{ {
DWORD dwValue; DWORD dwValue;
autoBstr bstrValue; autoBstr bstrValue;
VARIANT vtValue = { VT_EMPTY }; VARIANT vtValue = { VT_EMPTY };
bool bValue; bool bValue;
LONG lValue;
ULONGLONG ullValue;
HRESULT hres;
sstream << "symTag: "; hres = _symbol->get_offset(&lValue);
HRESULT hres = m_symbol->get_symTag(&dwValue); if (S_OK == hres)
sstream << ".[" << std::dec << lValue << + "] ";
hres = _symbol->get_symTag(&dwValue);
if ((S_OK == hres) && dwValue < _countof(symTagName)) if ((S_OK == hres) && dwValue < _countof(symTagName))
{
sstream << symTagName[dwValue].second; sstream << symTagName[dwValue].second;
if (SymTagUDT == symTagName[dwValue].first)
{
hres = _symbol->get_udtKind(&dwValue);
if ((S_OK == hres) && (dwValue < cntUdtKindName))
sstream << ":" << udtKindName[dwValue].second;
}
}
else else
sstream << "<unknown>"; {
sstream << "!unknown!";
}
sstream << ", "; sstream << ", ";
hres = m_symbol->get_name(&bstrValue); hres = _symbol->get_name(&bstrValue);
if (S_OK == hres) if (S_OK == hres)
sstream << "\"" << bstrValue.asStr().c_str() << "\""; sstream << "\"" << bstrValue.asStr().c_str() << "\"";
else else
sstream << "<no-name>"; sstream << "<no-name>";
bstrValue.free(); bstrValue.free();
hres = m_symbol->get_locationType(&dwValue); hres = _symbol->get_length(&ullValue);
if (S_OK == hres)
sstream << ", Length: 0x" << std::hex << ullValue;
hres = _symbol->get_locationType(&dwValue);
if ((S_OK == hres) && dwValue < _countof(locTypeName)) if ((S_OK == hres) && dwValue < _countof(locTypeName))
{ {
sstream << std::endl; sstream << ", Location: " << locTypeName[dwValue].second;
sstream << "Location: " << locTypeName[dwValue].second;
if (dwValue == LocIsStatic) if (LocIsBitField == locTypeName[dwValue].first)
{ {
hres = m_symbol->get_relativeVirtualAddress(&dwValue); hres = _symbol->get_bitPosition(&dwValue);
if (S_OK == hres)
sstream << ", Bit position: " << dwValue;
}
hres = _symbol->get_relativeVirtualAddress(&dwValue);
if (S_OK == hres) if (S_OK == hres)
sstream << ", RVA: 0x" << std::hex << dwValue; sstream << ", RVA: 0x" << std::hex << dwValue;
} }
}
bValue = false; bValue = false;
try try
{ {
getValueImpl(vtValue); getValueImpl(_symbol, vtValue);
bValue = true; bValue = true;
} }
catch (const Exception &except) catch (const Exception &except)
@ -473,19 +517,19 @@ std::string Symbol::print()
{ {
case VT_I1: case VT_I1:
case VT_UI1: case VT_UI1:
sstream << std::endl << "Value is "; sstream << ", Value: ";
sstream << std::hex << "0x" << vtValue.bVal; sstream << "0x" << std::hex << vtValue.bVal;
break; break;
case VT_BOOL: case VT_BOOL:
sstream << std::endl << "Value is "; sstream << ", Value: ";
sstream << vtValue.iVal ? "True" : "False"; sstream << vtValue.iVal ? "True" : "False";
break; break;
case VT_I2: case VT_I2:
case VT_UI2: case VT_UI2:
sstream << std::endl << "Value is "; sstream << ", Value: ";
sstream << std::hex << "0x" << vtValue.iVal; sstream << "0x" << std::hex << vtValue.iVal;
break; break;
case VT_I4: case VT_I4:
@ -494,46 +538,86 @@ std::string Symbol::print()
case VT_UINT: case VT_UINT:
case VT_ERROR: case VT_ERROR:
case VT_HRESULT: case VT_HRESULT:
sstream << std::endl << "Value is "; sstream << ", Value: ";
sstream << std::hex << "0x" << vtValue.lVal; sstream << "0x" << std::hex << vtValue.lVal;
break; break;
case VT_I8: case VT_I8:
case VT_UI8: case VT_UI8:
sstream << std::endl << "Value is "; sstream << ", Value: ";
sstream << std::hex << "0x" << vtValue.llVal; sstream << "0x" << std::hex << vtValue.llVal;
break; break;
case VT_R4: case VT_R4:
sstream << std::endl << "Value is "; sstream << ", Value: ";
sstream << vtValue.fltVal; sstream << vtValue.fltVal;
break; break;
case VT_R8: case VT_R8:
sstream << std::endl << "Value is "; sstream << ", Value: ";
sstream << vtValue.dblVal; sstream << vtValue.dblVal;
break; break;
case VT_BSTR: case VT_BSTR:
sstream << std::endl << "Value is "; sstream << ", Value: ";
sstream << "\"" << autoBstr::asStr(vtValue.bstrVal).c_str() << "\""; sstream << "\"" << autoBstr::asStr(vtValue.bstrVal).c_str() << "\"";
break; break;
} }
} }
hres = m_symbol->get_baseType(&dwValue); hres = _symbol->get_baseType(&dwValue);
if (SUCCEEDED(hres) && btNoType != dwValue) if (SUCCEEDED(hres) && btNoType != dwValue)
{ {
for (ULONG i = 0; i < cntBasicTypeName; ++i) for (ULONG i = 0; i < cntBasicTypeName; ++i)
{ {
if (basicTypeName[i].first == dwValue) if (basicTypeName[i].first == dwValue)
{ {
sstream << std::endl; sstream << ", Basic type: " << basicTypeName[i].second;
sstream << "Basic type is " << basicTypeName[i].second;
break; break;
} }
} }
} }
DWORD dwThisSymbol = 0;
hres = _symbol->get_symIndexId(&dwThisSymbol);
assert(S_OK == hres);
if (S_OK == hres)
{
DiaSymbolPtr pType;
hres = _symbol->get_type(&pType);
if (S_OK == hres)
{
DWORD dwTypeSymbol;
hres = pType->get_symIndexId(&dwTypeSymbol);
if ((S_OK == hres) && (dwTypeSymbol != dwThisSymbol))
{
sstream << std::endl;
for (ULONG i =0; i < indent; ++i)
sstream << " ";
sstream << "Type: " << std::endl;
sstream << printImpl(pType, indent + 1).c_str();
}
}
}
DiaEnumSymbolsPtr symbols;
hres =
_symbol->findChildren(
SymTagNull,
NULL,
nsCaseSensitive,
&symbols);
if (S_OK == hres)
{
DiaSymbolPtr child;
ULONG celt;
while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
{
sstream << std::endl << printImpl(child, indent + 1).c_str();
child.Release();
}
}
} }
return sstream.str(); return sstream.str();
} }

View File

@ -94,9 +94,9 @@ public:
ULONG getLocType(); ULONG getLocType();
ULONG getOffset(); LONG getOffset();
void getValueImpl(VARIANT &vtValue); static void getValueImpl(IDiaSymbol *_symbol, VARIANT &vtValue);
python::object getValue(); python::object getValue();
bool isBasicType(); bool isBasicType();
@ -130,6 +130,8 @@ public:
protected: protected:
static std::string printImpl(IDiaSymbol *_symbol, ULONG indent = 0);
template <typename TRet> template <typename TRet>
TRet callSymbolT( TRet callSymbolT(
HRESULT(STDMETHODCALLTYPE IDiaSymbol::*method)(TRet *), HRESULT(STDMETHODCALLTYPE IDiaSymbol::*method)(TRet *),

View File

@ -53,6 +53,12 @@ public:
virtual void virtFunc2() {} virtual void virtFunc2() {}
}; };
struct struct2 {
structTest m_struct;
unionTest m_union;
int m_field;
};
void FuncWithName0() void FuncWithName0()
{ {
classChild _classChild; classChild _classChild;
@ -67,6 +73,8 @@ void FuncWithName1()
_unionTest.m_value = 0; _unionTest.m_value = 0;
structTest _structTest; structTest _structTest;
_structTest.m_field1 = 1; _structTest.m_field1 = 1;
struct2 _struct2;
RtlZeroMemory(&_struct2, sizeof(_struct2));
} }
int _tmain(int argc, _TCHAR* argv[]) int _tmain(int argc, _TCHAR* argv[])