mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-19 19:13:22 +08:00
[+] offset into TypeInfo (for fields)
[+] method TypeInfo::build() for recursive typeClass building [+] virtual method printSelf() for address value for typedVarClass [~] remove trailing blanks, tabs replaced by spaces git-svn-id: https://pykd.svn.codeplex.com/svn@61693 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
5879200d07
commit
dfbbc434d3
@ -153,6 +153,7 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
boost::python::def( "setProcessorMode", &setProcessorMode );
|
||||
boost::python::class_<typeClass, boost::shared_ptr<typeClass> >( "typeClass" )
|
||||
.def("sizeof", &typeClass::size )
|
||||
.def("offset", &typeClass::getOffset )
|
||||
.def("__str__", &typeClass::print);
|
||||
boost::python::class_<typedVarClass, boost::python::bases<typeClass>, boost::shared_ptr<typedVarClass> >( "typedVarClass" )
|
||||
.def("getAddress", &typedVarClass::getAddress );
|
||||
|
@ -555,16 +555,16 @@ isOffsetValid( ULONG64 addr )
|
||||
return offsetInfo != DEBUG_VSOURCE_INVALID;
|
||||
|
||||
}
|
||||
catch( std::exception &e )
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||
}
|
||||
catch( std::exception &e )
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
152
pykd/dbgtype.cpp
152
pykd/dbgtype.cpp
@ -24,30 +24,29 @@ loadTypedVar( const std::string &moduleName, const std::string &typeName, ULONG6
|
||||
ULONG
|
||||
sizeofType( const std::string &moduleName, const std::string &typeName )
|
||||
{
|
||||
HRESULT hres;
|
||||
ULONG typeSize = ~0;
|
||||
HRESULT hres;
|
||||
ULONG typeSize = ~0;
|
||||
|
||||
try {
|
||||
|
||||
ULONG64 moduleBase;
|
||||
|
||||
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
||||
|
||||
typeSize = (ULONG)TypeInfo::get( moduleName, typeName ).size();
|
||||
}
|
||||
catch( std::exception &e )
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||
}
|
||||
|
||||
catch( std::exception &e )
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||
}
|
||||
|
||||
return typeSize;
|
||||
return typeSize;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
@ -55,20 +54,20 @@ sizeofType( const std::string &moduleName, const std::string &typeName )
|
||||
boost::python::object
|
||||
containingRecord( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &fieldName )
|
||||
{
|
||||
HRESULT hres;
|
||||
HRESULT hres;
|
||||
|
||||
try {
|
||||
|
||||
ULONG64 moduleBase;
|
||||
|
||||
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
||||
|
||||
ULONG typeId;
|
||||
hres = dbgExt->symbols->GetTypeId( moduleBase, typeName.c_str(), &typeId );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugSymbol::GetTypeId failed" );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugSymbol::GetTypeId failed" );
|
||||
|
||||
ULONG fieldTypeId;
|
||||
ULONG fieldOffset;
|
||||
@ -76,17 +75,16 @@ containingRecord( ULONG64 address, const std::string &moduleName, const std::str
|
||||
|
||||
return TypeInfo::get( moduleName, typeName ).load( address - fieldOffset );
|
||||
}
|
||||
catch( std::exception &e )
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||
}
|
||||
|
||||
catch( std::exception &e )
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||
}
|
||||
|
||||
return boost::python::object();
|
||||
return boost::python::object();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
@ -96,13 +94,7 @@ getTypeClass( const std::string &moduleName, const std::string &typeName )
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::shared_ptr<typeClass> ptr(
|
||||
new typeClass( TypeInfo::get( moduleName, typeName ))
|
||||
);
|
||||
boost::python::object var( ptr );
|
||||
ptr->setPyObj(var);
|
||||
|
||||
return var;
|
||||
return TypeInfo::get( moduleName, typeName ).build();
|
||||
}
|
||||
catch( std::exception &e )
|
||||
{
|
||||
@ -269,7 +261,7 @@ TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName
|
||||
m_size = 0;
|
||||
m_baseType = false;
|
||||
m_pointer = false;
|
||||
|
||||
m_offset = 0;
|
||||
try {
|
||||
|
||||
if ( typeName.find("*") < typeName.size() )
|
||||
@ -280,21 +272,21 @@ TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName
|
||||
}
|
||||
|
||||
m_baseType = isBaseType( typeName );
|
||||
if ( m_baseType )
|
||||
{
|
||||
if ( m_baseType )
|
||||
{
|
||||
setupBaseType();
|
||||
return;
|
||||
}
|
||||
|
||||
ULONG64 moduleBase = 0;
|
||||
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
||||
|
||||
ULONG typeId = 0;
|
||||
hres = dbgExt->symbols->GetTypeId( moduleBase, m_typeName.c_str(), &typeId );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugSymbol::GetTypeId failed" );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugSymbol::GetTypeId failed" );
|
||||
|
||||
hres = dbgExt->symbols->GetTypeSize( moduleBase, typeId, &m_size );
|
||||
if ( FAILED( hres ) )
|
||||
@ -330,22 +322,57 @@ TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName
|
||||
|
||||
m_fields.push_back( TypeField( fieldName, get(moduleName, fieldTypeName), fieldSize, fieldOffset ) );
|
||||
}
|
||||
|
||||
}
|
||||
catch( std::exception &e )
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||
}
|
||||
catch( std::exception &e )
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
boost::python::object
|
||||
TypeInfo::load( ULONG64 addr ) const
|
||||
TypeInfo::build( ULONG offset /* = 0 */ ) const
|
||||
{
|
||||
boost::shared_ptr<typeClass> ptr( new typeClass( *this ) );
|
||||
boost::python::object var( ptr );
|
||||
ptr->setPyObj( var );
|
||||
ptr->getTypeInfo().setOffset(offset);
|
||||
|
||||
TypeFieldList::const_iterator field = m_fields.begin();
|
||||
for ( field = m_fields.begin(); field != m_fields.end(); ++field )
|
||||
{
|
||||
|
||||
if ( field->size == field->type.size() )
|
||||
{
|
||||
var.attr( field->name.c_str() ) =
|
||||
field->type.build( offset + field->offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::python::dict arr;
|
||||
|
||||
for ( unsigned int i = 0; i < field->size / field->type.size(); ++i )
|
||||
{
|
||||
const ULONG locOffset = field->offset + i * (ULONG)field->type.size();
|
||||
arr[i] = field->type.build( offset + locOffset );
|
||||
}
|
||||
|
||||
var.attr( field->name.c_str() ) = arr;
|
||||
}
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
boost::python::object
|
||||
TypeInfo::load( ULONG64 addr, ULONG offset /* = 0 */ ) const
|
||||
{
|
||||
if ( !isOffsetValid( addr) )
|
||||
return boost::python::object();
|
||||
@ -359,6 +386,7 @@ TypeInfo::load( ULONG64 addr ) const
|
||||
boost::shared_ptr<typedVarClass> ptr( new typedVarClass( *this, addr ) );
|
||||
boost::python::object var( ptr );
|
||||
ptr->setPyObj( var );
|
||||
ptr->getTypeInfo().setOffset(offset);
|
||||
|
||||
TypeFieldList::const_iterator field = m_fields.begin();
|
||||
for ( field = m_fields.begin(); field != m_fields.end(); ++field )
|
||||
@ -366,15 +394,18 @@ TypeInfo::load( ULONG64 addr ) const
|
||||
|
||||
if ( field->size == field->type.size() )
|
||||
{
|
||||
var.attr( field->name.c_str() ) = field->type.load( addr + field->offset );
|
||||
|
||||
var.attr( field->name.c_str() ) =
|
||||
field->type.load( addr + field->offset, offset + field->offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::python::dict arr;
|
||||
|
||||
for ( unsigned int i = 0; i < field->size / field->type.size(); ++i )
|
||||
arr[i] = field->type.load( addr + field->offset + i * field->type.size() );
|
||||
{
|
||||
const ULONG locOffset = field->offset + i * (ULONG)field->type.size();
|
||||
arr[i] = field->type.load( addr + locOffset, offset + locOffset );
|
||||
}
|
||||
|
||||
var.attr( field->name.c_str() ) = arr;
|
||||
}
|
||||
@ -466,14 +497,17 @@ std::string typeClass::print() const
|
||||
{
|
||||
stringstream sstr;
|
||||
|
||||
sstr << getTypeInfo().name() << std::endl;
|
||||
sstr << getTypeInfo().name() << " ";
|
||||
printSelf(sstr);
|
||||
sstr << std::endl;
|
||||
|
||||
TypeInfo::TypeFieldList::const_iterator itField =
|
||||
getTypeInfo().getFields().begin();
|
||||
while (itField != getTypeInfo().getFields().end())
|
||||
{
|
||||
sstr << "\t" << hex << "+" << itField->offset;
|
||||
sstr << " " << itField->name << " ";
|
||||
sstr << "\t" << hex << "+" << itField->offset << " ";
|
||||
sstr << itField->type.name() << " ";
|
||||
sstr << itField->name << " ";
|
||||
|
||||
printField(*itField, sstr);
|
||||
|
||||
|
@ -85,13 +85,18 @@ public:
|
||||
TypeInfo() :
|
||||
m_size( 0 ),
|
||||
m_baseType( false ),
|
||||
m_pointer( false )
|
||||
m_pointer( false ),
|
||||
m_offset(0)
|
||||
{}
|
||||
|
||||
TypeInfo( const std::string &moduleName, const std::string &typeName );
|
||||
|
||||
boost::python::object
|
||||
load( ULONG64 addr ) const;
|
||||
load( ULONG64 addr, ULONG offset = 0 ) const;
|
||||
|
||||
boost::python::object
|
||||
build( ULONG offset = 0 ) const;
|
||||
|
||||
|
||||
ULONG64
|
||||
size() const
|
||||
@ -123,6 +128,10 @@ public:
|
||||
return m_pointer;
|
||||
}
|
||||
|
||||
// field offset getter/setter
|
||||
void setOffset(ULONG offset) { m_offset = offset; }
|
||||
ULONG getOffset() const { return m_offset; }
|
||||
|
||||
private:
|
||||
|
||||
static TypeInfoMap g_typeInfoCache;
|
||||
@ -145,6 +154,7 @@ private:
|
||||
TypeFieldList m_fields;
|
||||
std::string m_typeName;
|
||||
ULONG m_size;
|
||||
ULONG m_offset;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
@ -163,9 +173,10 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
// sizeof(TYPE)
|
||||
ULONG size() const
|
||||
{
|
||||
return m_typeInfo.size();
|
||||
return (ULONG)m_typeInfo.size();
|
||||
}
|
||||
|
||||
void setPyObj( const boost::python::object &obj )
|
||||
@ -173,6 +184,7 @@ public:
|
||||
m_pyobj = obj;
|
||||
}
|
||||
|
||||
// TypeInfo getter
|
||||
TypeInfo &getTypeInfo()
|
||||
{
|
||||
return m_typeInfo;
|
||||
@ -182,6 +194,7 @@ public:
|
||||
return m_typeInfo;
|
||||
}
|
||||
|
||||
// boost::python::object getter
|
||||
boost::python::object &getPyObj()
|
||||
{
|
||||
return m_pyobj;
|
||||
@ -200,6 +213,14 @@ public:
|
||||
{
|
||||
// no data - nothing print
|
||||
}
|
||||
virtual void printSelf(
|
||||
std::stringstream &sstr
|
||||
) const
|
||||
{
|
||||
// no data - nothing print
|
||||
}
|
||||
|
||||
ULONG getOffset() const { return m_typeInfo.getOffset(); }
|
||||
|
||||
private:
|
||||
TypeInfo m_typeInfo;
|
||||
@ -226,7 +247,13 @@ public:
|
||||
}
|
||||
|
||||
virtual void
|
||||
printField(const TypeInfo::TypeField &field, std::stringstream &sstr) const override;
|
||||
printField( const TypeInfo::TypeField &field, std::stringstream &sstr ) const override;
|
||||
|
||||
virtual void
|
||||
printSelf( std::stringstream &sstr ) const override
|
||||
{
|
||||
sstr << std::hex << "0x" << getAddress() << std::dec << " ";
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user