mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 11:43:23 +08:00

[~] pyDia: exception handling in tests git-svn-id: https://pykd.svn.codeplex.com/svn@69989 9b283d60-5439-405e-af05-b73fd8c4d996
299 lines
8.0 KiB
C++
299 lines
8.0 KiB
C++
#include "stdafx.h"
|
|
|
|
#include "diawrapper.h"
|
|
#include "utils.h"
|
|
|
|
namespace pyDia {
|
|
|
|
static void printVariant(
|
|
__in const VARIANT &vtValue,
|
|
__out std::stringstream &sstream
|
|
)
|
|
{
|
|
switch (vtValue.vt)
|
|
{
|
|
case VT_I1:
|
|
case VT_UI1:
|
|
sstream << ", Value: ";
|
|
sstream << "0x" << std::hex << vtValue.bVal;
|
|
break;
|
|
|
|
case VT_BOOL:
|
|
sstream << ", Value: ";
|
|
sstream << vtValue.iVal ? "True" : "False";
|
|
break;
|
|
|
|
case VT_I2:
|
|
case VT_UI2:
|
|
sstream << ", Value: ";
|
|
sstream << "0x" << std::hex << vtValue.iVal;
|
|
break;
|
|
|
|
case VT_I4:
|
|
case VT_UI4:
|
|
case VT_INT:
|
|
case VT_UINT:
|
|
case VT_ERROR:
|
|
case VT_HRESULT:
|
|
sstream << ", Value: ";
|
|
sstream << "0x" << std::hex << vtValue.lVal;
|
|
break;
|
|
|
|
case VT_I8:
|
|
case VT_UI8:
|
|
sstream << ", Value: ";
|
|
sstream << "0x" << std::hex << vtValue.llVal;
|
|
break;
|
|
|
|
case VT_R4:
|
|
sstream << ", Value: ";
|
|
sstream << vtValue.fltVal;
|
|
break;
|
|
|
|
case VT_R8:
|
|
sstream << ", Value: ";
|
|
sstream << vtValue.dblVal;
|
|
break;
|
|
|
|
case VT_BSTR:
|
|
sstream << ", Value: ";
|
|
sstream << "\"" << autoBstr::asStr(vtValue.bstrVal).c_str() << "\"";
|
|
break;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
std::string Symbol::printImpl(
|
|
IDiaSymbol *_symbol,
|
|
DWORD machineType,
|
|
ULONG indent /*= 0*/,
|
|
Symbol::checkSymLoop *checkLoopPrev /*= NULL*/,
|
|
const char *prefix /*= NULL*/
|
|
)
|
|
{
|
|
assert(_symbol);
|
|
|
|
std::stringstream sstream;
|
|
for (ULONG i =0; i < indent; ++i)
|
|
sstream << " ";
|
|
if (prefix)
|
|
sstream << prefix;
|
|
|
|
checkSymLoop _loop(checkLoopPrev, _symbol);
|
|
if (_loop.check())
|
|
{
|
|
sstream << "<...see above...>";
|
|
return sstream.str();
|
|
}
|
|
|
|
DWORD dwValue;
|
|
autoBstr bstrValue;
|
|
VARIANT vtValue = { VT_EMPTY };
|
|
bool bValue;
|
|
LONG lValue;
|
|
ULONGLONG ullValue;
|
|
HRESULT hres;
|
|
|
|
DWORD locType = LocIsNull;
|
|
hres = _symbol->get_locationType(&locType);
|
|
bool bLocation = (S_OK == hres);
|
|
if (bLocation)
|
|
{
|
|
hres = _symbol->get_offset(&lValue);
|
|
const bool bNegOffset = lValue < 0;
|
|
lValue = bNegOffset ? -1 * lValue : lValue;
|
|
|
|
switch (locType)
|
|
{
|
|
case LocIsBitField:
|
|
case LocIsThisRel:
|
|
assert(S_OK == hres);
|
|
sstream << (bNegOffset ? "-" : "+") << "0x" << std::hex << lValue;
|
|
if (LocIsBitField == locType)
|
|
{
|
|
hres = _symbol->get_bitPosition(&dwValue);
|
|
if (S_OK == hres)
|
|
sstream << ", Bit position: " << dwValue;
|
|
}
|
|
break;
|
|
|
|
case LocIsEnregistered:
|
|
case LocIsRegRel:
|
|
hres = _symbol->get_registerId(&dwValue);
|
|
if (S_OK == hres)
|
|
{
|
|
const char *regName = NULL;
|
|
if (IMAGE_FILE_MACHINE_I386 == machineType)
|
|
{
|
|
for (ULONG i = 0; i < cntI386RegName; ++i)
|
|
{
|
|
if (dwValue == i386RegName[i].first)
|
|
{
|
|
regName = i386RegName[i].second;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if (IMAGE_FILE_MACHINE_AMD64 == machineType)
|
|
{
|
|
for (ULONG i = 0; i < cntI386RegName; ++i)
|
|
{
|
|
if (dwValue == i386RegName[i].first)
|
|
{
|
|
regName = i386RegName[i].second;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!regName)
|
|
{
|
|
sstream << locTypeName[locType].second;
|
|
}
|
|
else
|
|
{
|
|
if (LocIsEnregistered == locType)
|
|
{
|
|
sstream << regName;
|
|
}
|
|
else
|
|
{
|
|
sstream << "[" << regName;
|
|
sstream << (bNegOffset ? "-" : "+") << "0x" << std::hex << lValue;
|
|
sstream << "]";
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sstream << locTypeName[locType].second;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if (S_OK == _symbol->get_relativeVirtualAddress(&dwValue))
|
|
sstream << "RVA:0x" << std::hex << dwValue;
|
|
else if (locType < _countof(locTypeName))
|
|
sstream << "Location: " << locTypeName[locType].second;
|
|
if (S_OK == hres)
|
|
{
|
|
sstream << ", Offset: ";
|
|
sstream << (bNegOffset ? "-" : "+") << "0x" << std::hex << lValue;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool bFuncDebugRange = false;
|
|
|
|
hres = _symbol->get_symTag(&dwValue);
|
|
if ((S_OK == hres) && dwValue < _countof(symTagName))
|
|
{
|
|
if (bLocation)
|
|
sstream << ", ";
|
|
|
|
sstream << symTagName[dwValue].second;
|
|
if ((S_OK == _symbol->get_udtKind(&dwValue)) && (dwValue < cntUdtKindName))
|
|
sstream << ": " << udtKindName[dwValue].second;
|
|
|
|
if (S_OK == _symbol->get_count(&dwValue))
|
|
sstream << ", Count: " << std::dec << dwValue;
|
|
|
|
bFuncDebugRange =
|
|
(SymTagFuncDebugStart == symTagName[dwValue].first) ||
|
|
(SymTagFuncDebugEnd == symTagName[dwValue].first);
|
|
}
|
|
else
|
|
{
|
|
sstream << "!invalid symTag!";
|
|
}
|
|
sstream << ", ";
|
|
|
|
hres = _symbol->get_name(&bstrValue);
|
|
if (S_OK == hres)
|
|
sstream << "\"" << bstrValue.asStr().c_str() << "\"";
|
|
else
|
|
sstream << "<no-name>";
|
|
bstrValue.free();
|
|
|
|
hres = _symbol->get_length(&ullValue);
|
|
if (S_OK == hres)
|
|
sstream << ", Length: 0x" << std::hex << ullValue;
|
|
|
|
bValue = false;
|
|
try
|
|
{
|
|
getValueImpl(_symbol, vtValue);
|
|
bValue = true;
|
|
}
|
|
catch (const Exception &except)
|
|
{
|
|
DBG_UNREFERENCED_PARAMETER(except);
|
|
}
|
|
if (bValue)
|
|
printVariant(vtValue, sstream);
|
|
|
|
hres = _symbol->get_baseType(&dwValue);
|
|
if (SUCCEEDED(hres) && btNoType != dwValue)
|
|
{
|
|
for (ULONG i = 0; i < cntBasicTypeName; ++i)
|
|
{
|
|
if (basicTypeName[i].first == dwValue)
|
|
{
|
|
sstream << ", Basic type: " << basicTypeName[i].second;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
DiaSymbolPtr pType;
|
|
hres = _symbol->get_type(&pType);
|
|
if (S_OK == hres)
|
|
{
|
|
sstream << std::endl;
|
|
sstream << printImpl(pType, machineType, indent+1, &_loop, "Type: ").c_str();
|
|
}
|
|
|
|
if (bFuncDebugRange)
|
|
return sstream.str();
|
|
|
|
DiaEnumSymbolsPtr symbols;
|
|
hres =
|
|
_symbol->findChildren(
|
|
SymTagNull,
|
|
NULL,
|
|
nsCaseSensitive,
|
|
&symbols);
|
|
if (S_OK == hres)
|
|
{
|
|
if (indent <= 2)
|
|
{
|
|
DiaSymbolPtr child;
|
|
ULONG celt;
|
|
while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
|
|
{
|
|
sstream << std::endl;
|
|
sstream << printImpl(child, machineType, indent + 1, &_loop).c_str();
|
|
child.Release();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lValue = 0;
|
|
symbols->get_Count(&lValue);
|
|
if (lValue)
|
|
{
|
|
sstream << std::endl;
|
|
for (ULONG i =0; i < indent+1; ++i)
|
|
sstream << " ";
|
|
sstream << "<...>";
|
|
}
|
|
}
|
|
}
|
|
return sstream.str();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}
|