[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
This commit is contained in:
SND\kernelnet_cp 2012-02-28 07:09:33 +00:00 committed by Mikhail I. Izmestev
parent f15f01a155
commit 4033f95230
6 changed files with 312 additions and 41 deletions

View File

@ -1,4 +1,6 @@
version 0.1.0.8 10/02/2012
[!] fixed : issue #10335 ( VirtualToOffset: not properly sign extended ) [!] fixed : issue #10335 ( VirtualToOffset: not properly sign extended )
[!] fixed : issue #10336 ( pykd routines can not convert parameters to long ) [!] fixed : issue #10336 ( pykd routines can not convert parameters to long )

View File

@ -1,5 +1,7 @@
#include "stdafx.h" #include "stdafx.h"
#include <iomanip>
#include "typedvar.h" #include "typedvar.h"
#include "dbgclient.h" #include "dbgclient.h"
#include "dbgmem.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() BaseTypeVariant PtrTypedVar::getValue()
{ {
ULONG64 val = 0; 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 TypedVarPtr
UdtTypedVar::getField( const std::string &fieldName ) 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() BaseTypeVariant BitFieldVar::getValue()
{ {
ULONG64 val = 0; ULONG64 val = 0;
@ -174,6 +284,19 @@ BaseTypeVariant BitFieldVar::getValue()
throw DbgException( "failed get value " ); throw DbgException( "failed get value " );
} }
///////////////////////////////////////////////////////////////////////////////////
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() BaseTypeVariant EnumTypedVar::getValue()
@ -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 } // end pykd namespace

View File

@ -38,15 +38,19 @@ public:
} }
virtual TypedVarPtr deref() { 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 ) { virtual TypedVarPtr getField( const std::string &fieldName ) {
throw DbgException("no fields"); throw TypeException( m_typeInfo->getName(), "no fields");
} }
virtual std::string print() { virtual std::string print() {
return "TypedVar"; return "";
}
virtual std::string printValue() {
return "";
} }
virtual ULONG getElementCount() { virtual ULONG getElementCount() {
@ -61,6 +65,10 @@ public:
return getElementByIndex( boost::apply_visitor( VariantToULong(), tv->getValue() ) ); return getElementByIndex( boost::apply_visitor( VariantToULong(), tv->getValue() ) );
} }
virtual BaseTypeVariant getValue() {
return m_offset;
}
ULONG getDataKind() const { ULONG getDataKind() const {
return m_dataKind; return m_dataKind;
} }
@ -73,10 +81,6 @@ protected:
TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ); TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset );
virtual BaseTypeVariant getValue() {
return m_offset;
}
TypeInfoPtr m_typeInfo; TypeInfoPtr m_typeInfo;
ULONG64 m_offset; ULONG64 m_offset;
@ -86,6 +90,7 @@ protected:
ULONG m_dataKind; ULONG m_dataKind;
}; };
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
class BasicTypedVar : public TypedVar { class BasicTypedVar : public TypedVar {
@ -95,9 +100,9 @@ public:
BasicTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} BasicTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){}
virtual std::string print() { virtual std::string print();
return intBase::str();
} virtual std::string printValue();
virtual BaseTypeVariant getValue(); virtual BaseTypeVariant getValue();
@ -111,14 +116,9 @@ public:
PtrTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} PtrTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){}
TypedVarPtr virtual std::string print();
virtual getField( const std::string &fieldName ) {
throw DbgException("no fields");
}
virtual std::string print() { virtual std::string printValue();
return "PtrTypedVar";
}
virtual TypedVarPtr deref(); virtual TypedVarPtr deref();
@ -138,17 +138,11 @@ public:
return m_typeInfo->getCount(); return m_typeInfo->getCount();
} }
virtual TypedVarPtr getElementByIndex( ULONG index ) virtual std::string print();
{
if ( index >= m_typeInfo->getCount() )
{
throw PyException( PyExc_IndexError, "Index out of range" );
}
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,6 +153,10 @@ public:
UdtTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} UdtTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){}
virtual std::string print();
virtual std::string printValue();
virtual TypedVarPtr getField( const std::string &fieldName ); virtual TypedVarPtr getField( const std::string &fieldName );
}; };
@ -170,9 +168,7 @@ public:
BitFieldVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} BitFieldVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){}
virtual std::string print() { virtual std::string printValue();
return intBase::str();
}
virtual BaseTypeVariant getValue(); virtual BaseTypeVariant getValue();
}; };
@ -184,6 +180,10 @@ public:
EnumTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} EnumTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){}
virtual std::string print();
virtual std::string printValue();
virtual BaseTypeVariant getValue(); virtual BaseTypeVariant getValue();
}; };

View File

@ -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 bool
UdtTypeInfo::getBaseField( UdtTypeInfo::getBaseField(
pyDia::SymbolPtr symUdt, 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 EnumTypeInfo::asMap()
{ {
python::dict dct; python::dict dct;

View File

@ -43,6 +43,18 @@ public:
throw TypeException( getName(), "type is not a struct" ); 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 BaseTypeVariant getValue();
virtual bool isBasicType() { virtual bool isBasicType() {
@ -210,6 +222,12 @@ protected:
virtual TypeInfoPtr getField( const std::string &fieldName ); virtual TypeInfoPtr getField( const std::string &fieldName );
virtual TypeInfoPtr getFieldByIndex( ULONG index );
virtual std::string getFieldNameByIndex( ULONG index );
virtual ULONG getFieldCount();
virtual bool isUserDefined() { virtual bool isUserDefined() {
return true; return true;
} }
@ -245,12 +263,13 @@ protected:
return (ULONG)m_dia->getSize(); return (ULONG)m_dia->getSize();
} }
virtual TypeInfoPtr getField( const std::string &fieldName ) { virtual TypeInfoPtr getFieldByIndex( ULONG index );
pyDia::SymbolPtr field = m_dia->getChildByName( fieldName );
TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, fieldName ); virtual std::string getFieldNameByIndex( ULONG index );
ti->setOffset( 0 );
return ti; virtual ULONG getFieldCount();
}
virtual TypeInfoPtr getField( const std::string &fieldName );
virtual python::dict asMap(); virtual python::dict asMap();

View File

@ -45,7 +45,8 @@ def getTestSuite( singleName = "" ):
unittest.TestLoader().loadTestsFromTestCase( thrdctxtest.ThreadContextTest ), unittest.TestLoader().loadTestsFromTestCase( thrdctxtest.ThreadContextTest ),
unittest.TestLoader().loadTestsFromTestCase( ehloadtest.EhLoadTest ), unittest.TestLoader().loadTestsFromTestCase( ehloadtest.EhLoadTest ),
unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest ), unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest ),
unittest.TestLoader().loadTestsFromTestCase( ehexcepttest.EhExceptionBreakpointTest ) unittest.TestLoader().loadTestsFromTestCase( ehexcepttest.EhExceptionBreakpointTest ),
unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ),
] ) ] )
else: else:
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) ) return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )
@ -70,7 +71,7 @@ if __name__ == "__main__":
print "" print ""
suite = getTestSuite() suite = getTestSuite()
#suite = getTestSuite( "typedvar.TypedVarTest.testBitField" ) #suite = getTestSuite( "typedvar.TypedVarTest.testTypeVarArg" )
#suite = getTestSuite( "typeinfo.TypeInfoTest.testBitField" ) #suite = getTestSuite( "typeinfo.TypeInfoTest.testBitField" )
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite ) unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite )