From 4033f95230b929c69beab44ac70c30beca30631a Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Tue, 28 Feb 2012 07:09:33 +0000 Subject: [PATCH] [0.1.x] added : typedVar __str__ converter ( base class is not printed ) git-svn-id: https://pykd.svn.codeplex.com/svn@74615 9b283d60-5439-405e-af05-b73fd8c4d996 --- changelist.txt | 2 + pykd/typedvar.cpp | 164 ++++++++++++++++++++++++++++++++++++++- pykd/typedvar.h | 60 +++++++------- pykd/typeinfo.cpp | 87 +++++++++++++++++++++ pykd/typeinfo.h | 33 ++++++-- test/scripts/pykdtest.py | 7 +- 6 files changed, 312 insertions(+), 41 deletions(-) diff --git a/changelist.txt b/changelist.txt index 0967689..ae63e75 100644 --- a/changelist.txt +++ b/changelist.txt @@ -1,4 +1,6 @@ +version 0.1.0.8 10/02/2012 + [!] fixed : issue #10335 ( VirtualToOffset: not properly sign extended ) [!] fixed : issue #10336 ( pykd routines can not convert parameters to long ) diff --git a/pykd/typedvar.cpp b/pykd/typedvar.cpp index e3da50f..15e4d59 100644 --- a/pykd/typedvar.cpp +++ b/pykd/typedvar.cpp @@ -1,5 +1,7 @@ #include "stdafx.h" +#include + #include "typedvar.h" #include "dbgclient.h" #include "dbgmem.h" @@ -115,6 +117,30 @@ BaseTypeVariant BasicTypedVar::getValue() /////////////////////////////////////////////////////////////////////////////////// +std::string BasicTypedVar::print() +{ + std::stringstream sstr; + + sstr << m_typeInfo->getName() << " at " << std::hex << m_offset; + sstr << " Value: " << printValue(); + + return sstr.str(); +} + +/////////////////////////////////////////////////////////////////////////////////// + +std::string BasicTypedVar::printValue() +{ + std::stringstream sstr; + + sstr << "0x" << boost::apply_visitor( VariantToHex(), getValue() ); + sstr << " (" << boost::apply_visitor( VariantToStr(), getValue() ) << ")"; + + return sstr.str(); +} + +/////////////////////////////////////////////////////////////////////////////////// + BaseTypeVariant PtrTypedVar::getValue() { ULONG64 val = 0; @@ -137,6 +163,59 @@ TypedVarPtr PtrTypedVar::deref() /////////////////////////////////////////////////////////////////////////////////// +std::string PtrTypedVar::print() +{ + std::stringstream sstr; + + sstr << m_typeInfo->getName() << " at 0x" << std::hex << m_offset; + sstr << " Value: " << printValue(); + + return sstr.str(); +} + +/////////////////////////////////////////////////////////////////////////////////// + +std::string PtrTypedVar::printValue() +{ + std::stringstream sstr; + + sstr << "0x" << boost::apply_visitor( VariantToHex(), getValue() ); + + return sstr.str(); +} + +/////////////////////////////////////////////////////////////////////////////////// + +std::string ArrayTypedVar::print() +{ + std::stringstream sstr; + + sstr << m_typeInfo->getName() << " at 0x" << std::hex << m_offset; + + return sstr.str(); +} + +/////////////////////////////////////////////////////////////////////////////////// + +std::string ArrayTypedVar::printValue() +{ + return ""; +} + +/////////////////////////////////////////////////////////////////////////////////// + +TypedVarPtr ArrayTypedVar::getElementByIndex( ULONG index ) +{ + if ( index >= m_typeInfo->getCount() ) + throw PyException( PyExc_IndexError, "Index out of range" ); + + TypeInfoPtr elementType = m_typeInfo->getElementType(); + + return TypedVar::getTypedVar( m_client, elementType, m_offset + elementType->getSize()*index ); +} + +/////////////////////////////////////////////////////////////////////////////////// + TypedVarPtr UdtTypedVar::getField( const std::string &fieldName ) { @@ -147,6 +226,37 @@ UdtTypedVar::getField( const std::string &fieldName ) /////////////////////////////////////////////////////////////////////////////////// +std::string UdtTypedVar::print() +{ + std::stringstream sstr; + + sstr << "struct/class: " << m_typeInfo->getName() << " at 0x" << std::hex << m_offset << std::endl; + + for ( ULONG i = 0; i < m_typeInfo->getFieldCount(); ++i ) + { + TypeInfoPtr fieldType = m_typeInfo->getFieldByIndex(i); + TypedVarPtr fieldVar = TypedVar::getTypedVar( m_client, fieldType, m_offset + fieldType->getOffset() ); + + sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldType->getOffset(); + sstr << " " << std::left << std::setw( 20 ) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':'; + sstr << " " << std::left << fieldType->getName(); + sstr << " " << fieldVar->printValue(); + + sstr << std::endl; + } + + return sstr.str(); +} + +/////////////////////////////////////////////////////////////////////////////////// + +std::string UdtTypedVar::printValue() +{ + return ""; +} + +/////////////////////////////////////////////////////////////////////////////////// + BaseTypeVariant BitFieldVar::getValue() { ULONG64 val = 0; @@ -174,9 +284,22 @@ BaseTypeVariant BitFieldVar::getValue() throw DbgException( "failed get value " ); } + /////////////////////////////////////////////////////////////////////////////////// -BaseTypeVariant EnumTypedVar::getValue() +std::string BitFieldVar::printValue() +{ + std::stringstream sstr; + + sstr << "0x" << boost::apply_visitor( VariantToHex(), getValue() ); + sstr << " (" << boost::apply_visitor( VariantToStr(), getValue() ) << ")"; + + return sstr.str(); +} + +/////////////////////////////////////////////////////////////////////////////////// + +BaseTypeVariant EnumTypedVar::getValue() { ULONG val = 0; @@ -187,4 +310,43 @@ BaseTypeVariant EnumTypedVar::getValue() /////////////////////////////////////////////////////////////////////////////////// +std::string EnumTypedVar::print() +{ + std::stringstream sstr; + + sstr << "enum: " << m_typeInfo->getName() << " at 0x" << std::hex << m_offset; + sstr << " Value: " << printValue(); + + return sstr.str(); +} + +/////////////////////////////////////////////////////////////////////////////////// + +std::string EnumTypedVar::printValue() +{ + std::stringstream sstr; + + ULONG val = boost::apply_visitor( VariantToULong(), getValue() ); + + for ( ULONG i = 0; i < m_typeInfo->getFieldCount(); ++i ) + { + ULONG val1 = boost::apply_visitor( VariantToULong(), m_typeInfo->getFieldByIndex(i)->getValue() ); + + if ( val == val1 ) + { + sstr << m_typeInfo->getFieldNameByIndex(i); + sstr << "(0x" << std::hex << val << ")"; + + return sstr.str(); + } + } + + sstr << "0x" << std::hex << val; + sstr << " ( No matching name )"; + + return sstr.str(); +} + +/////////////////////////////////////////////////////////////////////////////////// + } // end pykd namespace \ No newline at end of file diff --git a/pykd/typedvar.h b/pykd/typedvar.h index 6abd28f..1964fc3 100644 --- a/pykd/typedvar.h +++ b/pykd/typedvar.h @@ -38,15 +38,19 @@ public: } virtual TypedVarPtr deref() { - throw DbgException("object can not be derefernced" ); + throw TypeException( m_typeInfo->getName(), "object can not be derefernced" ); } virtual TypedVarPtr getField( const std::string &fieldName ) { - throw DbgException("no fields"); + throw TypeException( m_typeInfo->getName(), "no fields"); } virtual std::string print() { - return "TypedVar"; + return ""; + } + + virtual std::string printValue() { + return ""; } virtual ULONG getElementCount() { @@ -61,6 +65,10 @@ public: return getElementByIndex( boost::apply_visitor( VariantToULong(), tv->getValue() ) ); } + virtual BaseTypeVariant getValue() { + return m_offset; + } + ULONG getDataKind() const { return m_dataKind; } @@ -73,10 +81,6 @@ protected: TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ); - virtual BaseTypeVariant getValue() { - return m_offset; - } - TypeInfoPtr m_typeInfo; ULONG64 m_offset; @@ -86,6 +90,7 @@ protected: ULONG m_dataKind; }; + /////////////////////////////////////////////////////////////////////////////////// class BasicTypedVar : public TypedVar { @@ -95,9 +100,9 @@ public: BasicTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} - virtual std::string print() { - return intBase::str(); - } + virtual std::string print(); + + virtual std::string printValue(); virtual BaseTypeVariant getValue(); @@ -111,14 +116,9 @@ public: PtrTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} - TypedVarPtr - virtual getField( const std::string &fieldName ) { - throw DbgException("no fields"); - } + virtual std::string print(); - virtual std::string print() { - return "PtrTypedVar"; - } + virtual std::string printValue(); virtual TypedVarPtr deref(); @@ -138,17 +138,11 @@ public: return m_typeInfo->getCount(); } - virtual TypedVarPtr getElementByIndex( ULONG index ) - { - if ( index >= m_typeInfo->getCount() ) - { - throw PyException( PyExc_IndexError, "Index out of range" ); - } + virtual std::string print(); - TypeInfoPtr elementType = m_typeInfo->getElementType(); + virtual std::string printValue(); - return TypedVar::getTypedVar( m_client, elementType, m_offset + elementType->getSize()*index ); - } + virtual TypedVarPtr getElementByIndex( ULONG index ); }; /////////////////////////////////////////////////////////////////////////////////// @@ -159,7 +153,11 @@ public: UdtTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} - virtual TypedVarPtr getField( const std::string &fieldName ); + virtual std::string print(); + + virtual std::string printValue(); + + virtual TypedVarPtr getField( const std::string &fieldName ); }; /////////////////////////////////////////////////////////////////////////////////// @@ -170,9 +168,7 @@ public: BitFieldVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} - virtual std::string print() { - return intBase::str(); - } + virtual std::string printValue(); virtual BaseTypeVariant getValue(); }; @@ -184,6 +180,10 @@ public: EnumTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} + virtual std::string print(); + + virtual std::string printValue(); + virtual BaseTypeVariant getValue(); }; diff --git a/pykd/typeinfo.cpp b/pykd/typeinfo.cpp index fd887ed..5e06880 100644 --- a/pykd/typeinfo.cpp +++ b/pykd/typeinfo.cpp @@ -460,6 +460,45 @@ TypeInfoPtr UdtTypeInfo::getField( const std::string &fieldName ) ///////////////////////////////////////////////////////////////////////////////////// +TypeInfoPtr UdtTypeInfo::getFieldByIndex( ULONG index ) +{ + if ( index >= m_dia->getChildCount() ) + throw TypeException( m_dia->getName(), ": field not found" ); + + pyDia::SymbolPtr field = m_dia->getChildByIndex(index); + + if ( !field ) + throw TypeException( m_dia->getName(), ": field not found" ); + + TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, field ); + ti->setOffset( field->getOffset() ); + return ti; +} + +///////////////////////////////////////////////////////////////////////////////////// + +std::string UdtTypeInfo::getFieldNameByIndex( ULONG index ) +{ + if ( index >= m_dia->getChildCount() ) + throw TypeException( m_dia->getName(), ": field not found" ); + + pyDia::SymbolPtr field = m_dia->getChildByIndex(index); + + if ( !field ) + throw TypeException( m_dia->getName(), ": field not found" ); + + return field->getName(); +} + +///////////////////////////////////////////////////////////////////////////////////// + +ULONG UdtTypeInfo::getFieldCount() +{ + return m_dia->getChildCount(); +} + +///////////////////////////////////////////////////////////////////////////////////// + bool UdtTypeInfo::getBaseField( pyDia::SymbolPtr symUdt, @@ -510,6 +549,54 @@ UdtTypeInfo::getBaseField( ///////////////////////////////////////////////////////////////////////////////////// +TypeInfoPtr EnumTypeInfo::getField( const std::string &fieldName ) { + pyDia::SymbolPtr field = m_dia->getChildByName( fieldName ); + TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, fieldName ); + ti->setOffset( 0 ); + return ti; +} + +///////////////////////////////////////////////////////////////////////////////////// + +TypeInfoPtr EnumTypeInfo::getFieldByIndex( ULONG index ) +{ + if ( index >= m_dia->getChildCount() ) + throw TypeException( m_dia->getName(), ": field not found" ); + + pyDia::SymbolPtr field = m_dia->getChildByIndex(index); + + if ( !field ) + throw TypeException( m_dia->getName(), ": field not found" ); + + TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, field->getName() ); + ti->setOffset( 0 ); + return ti; +} + +///////////////////////////////////////////////////////////////////////////////////// + +std::string EnumTypeInfo::getFieldNameByIndex( ULONG index ) +{ + if ( index >= m_dia->getChildCount() ) + throw TypeException( m_dia->getName(), ": field not found" ); + + pyDia::SymbolPtr field = m_dia->getChildByIndex(index); + + if ( !field ) + throw TypeException( m_dia->getName(), ": field not found" ); + + return field->getName(); +} + +///////////////////////////////////////////////////////////////////////////////////// + +ULONG EnumTypeInfo::getFieldCount() +{ + return m_dia->getChildCount(); +} + +///////////////////////////////////////////////////////////////////////////////////// + python::dict EnumTypeInfo::asMap() { python::dict dct; diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h index 2493c9d..d4cc505 100644 --- a/pykd/typeinfo.h +++ b/pykd/typeinfo.h @@ -43,6 +43,18 @@ public: throw TypeException( getName(), "type is not a struct" ); } + virtual TypeInfoPtr getFieldByIndex( ULONG index ) { + throw TypeException( getName(), "type is not a struct" ); + } + + virtual std::string getFieldNameByIndex( ULONG index ) { + throw TypeException( getName(), "type is not a struct" ); + } + + virtual ULONG getFieldCount() { + throw TypeException( getName(), "type is not a struct" ); + } + virtual BaseTypeVariant getValue(); virtual bool isBasicType() { @@ -70,7 +82,7 @@ public: } virtual ULONG getCount() { - throw TypeException( getName(), "type is not an array" ); + throw TypeException( getName(), "type is not an array" ); } virtual TypeInfoPtr getElementType() { @@ -210,6 +222,12 @@ protected: virtual TypeInfoPtr getField( const std::string &fieldName ); + virtual TypeInfoPtr getFieldByIndex( ULONG index ); + + virtual std::string getFieldNameByIndex( ULONG index ); + + virtual ULONG getFieldCount(); + virtual bool isUserDefined() { return true; } @@ -245,12 +263,13 @@ protected: return (ULONG)m_dia->getSize(); } - virtual TypeInfoPtr getField( const std::string &fieldName ) { - pyDia::SymbolPtr field = m_dia->getChildByName( fieldName ); - TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, fieldName ); - ti->setOffset( 0 ); - return ti; - } + virtual TypeInfoPtr getFieldByIndex( ULONG index ); + + virtual std::string getFieldNameByIndex( ULONG index ); + + virtual ULONG getFieldCount(); + + virtual TypeInfoPtr getField( const std::string &fieldName ); virtual python::dict asMap(); diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py index 18bc71f..5c49277 100644 --- a/test/scripts/pykdtest.py +++ b/test/scripts/pykdtest.py @@ -45,7 +45,8 @@ def getTestSuite( singleName = "" ): unittest.TestLoader().loadTestsFromTestCase( thrdctxtest.ThreadContextTest ), unittest.TestLoader().loadTestsFromTestCase( ehloadtest.EhLoadTest ), unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest ), - unittest.TestLoader().loadTestsFromTestCase( ehexcepttest.EhExceptionBreakpointTest ) + unittest.TestLoader().loadTestsFromTestCase( ehexcepttest.EhExceptionBreakpointTest ), + unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ), ] ) else: return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) ) @@ -70,9 +71,9 @@ if __name__ == "__main__": print "" suite = getTestSuite() - #suite = getTestSuite( "typedvar.TypedVarTest.testBitField" ) + #suite = getTestSuite( "typedvar.TypedVarTest.testTypeVarArg" ) #suite = getTestSuite( "typeinfo.TypeInfoTest.testBitField" ) unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite ) - # raw_input("\npress return\n") + #raw_input("\npress return\n")