mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 12:53:23 +08:00
[~] hierarchical symbol print
git-svn-id: https://pykd.svn.codeplex.com/svn@69954 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
6091868478
commit
972236f451
@ -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)
|
if (S_OK == hres)
|
||||||
sstream << ", RVA: 0x" << std::hex << dwValue;
|
sstream << ", Bit position: " << dwValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hres = _symbol->get_relativeVirtualAddress(&dwValue);
|
||||||
|
if (S_OK == hres)
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
@ -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 *),
|
||||||
|
@ -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[])
|
||||||
|
Loading…
Reference in New Issue
Block a user