[0.1.x] added : typeInfo construction by type name

git-svn-id: https://pykd.svn.codeplex.com/svn@71384 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-11-16 06:42:00 +00:00 committed by Mikhail I. Izmestev
parent 82a744d1be
commit 1f350f90b7
13 changed files with 531 additions and 149 deletions

View File

@ -251,4 +251,23 @@ void waitForEvent()
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
ULONG DebugClient::ptrSize()
{
HRESULT hres;
hres = m_control->IsPointer64Bit();
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::IsPointer64Bit failed" );
return S_OK == hres ? 8 : 4;
}
ULONG ptrSize()
{
return g_dbgClient->ptrSize();
}
///////////////////////////////////////////////////////////////////////////////////
}; // end of namespace pykd }; // end of namespace pykd

View File

@ -119,6 +119,28 @@ public:
std::wstring loadWChars( ULONG64 offset, ULONG count, bool phyAddr = FALSE ); std::wstring loadWChars( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
ULONG ptrSize();
LONG64 ptrByte();
LONG64 ptrWord();
LONG64 ptrDWord();
LONG64 ptrQWord();
LONG64 ptrMWord();
ULONG64 ptrSignByte();
ULONG64 ptrSignWord();
ULONG64 ptrSignDWord();
ULONG64 ptrSignQWord();
ULONG64 ptrSignMWord();
void readMemory( ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE ); void readMemory( ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE );
void setExecutionStatus( ULONG status ); void setExecutionStatus( ULONG status );
@ -184,6 +206,8 @@ bool isKernelDebugging();
bool isDumpAnalyzing(); bool isDumpAnalyzing();
ULONG ptrSize();
void setExecutionStatus( ULONG status ); void setExecutionStatus( ULONG status );
void waitForEvent(); void waitForEvent();

View File

@ -218,6 +218,8 @@ BOOST_PYTHON_MODULE( pykd )
"Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" ) "Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" )
.def( "dprintln", &pykd::DebugClient::dprintln, .def( "dprintln", &pykd::DebugClient::dprintln,
"Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" ) "Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" )
.def( "ptrSize", &DebugClient::ptrSize,
"Return effective pointer size" )
.def( "setExecutionStatus", &pykd::DebugClient::setExecutionStatus, .def( "setExecutionStatus", &pykd::DebugClient::setExecutionStatus,
"Requests that the debugger engine enter an executable state" ) "Requests that the debugger engine enter an executable state" )
.def( "step", &pykd::DebugClient::changeDebuggerStatus<DEBUG_STATUS_STEP_OVER>, .def( "step", &pykd::DebugClient::changeDebuggerStatus<DEBUG_STATUS_STEP_OVER>,
@ -281,6 +283,8 @@ BOOST_PYTHON_MODULE( pykd )
"Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" ) ); "Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
python::def( "dprintln", &pykd::dprintln, dprintln_( boost::python::args( "str", "dml" ), python::def( "dprintln", &pykd::dprintln, dprintln_( boost::python::args( "str", "dml" ),
"Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" ) ); "Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
python::def( "ptrSize", &ptrSize,
"Return effective pointer size" );
python::def( "setExecutionStatus", &pykd::setExecutionStatus, python::def( "setExecutionStatus", &pykd::setExecutionStatus,
"Requests that the debugger engine enter an executable state" ); "Requests that the debugger engine enter an executable state" );
python::def( "step", &pykd::changeDebuggerStatus<DEBUG_STATUS_STEP_OVER>, python::def( "step", &pykd::changeDebuggerStatus<DEBUG_STATUS_STEP_OVER>,
@ -290,7 +294,7 @@ BOOST_PYTHON_MODULE( pykd )
python::def( "waitForEvent", &pykd::waitForEvent, python::def( "waitForEvent", &pykd::waitForEvent,
"Wait for events that breaks into the debugger" ); "Wait for events that breaks into the debugger" );
python::class_<pykd::TypeInfo>("typeInfo", "Class representing typeInfo", python::no_init ) python::class_<TypeInfo, TypeInfoPtr, boost::noncopyable >("typeInfo", "Class representing typeInfo", python::no_init )
.def( "name", &pykd::TypeInfo::getName ) .def( "name", &pykd::TypeInfo::getName )
.def( "size", &pykd::TypeInfo::getSize ) .def( "size", &pykd::TypeInfo::getSize )
.def( "offset", &pykd::TypeInfo::getOffset ) .def( "offset", &pykd::TypeInfo::getOffset )
@ -300,7 +304,7 @@ BOOST_PYTHON_MODULE( pykd )
python::class_<TypedVar, TypedVarPtr, python::bases<intBase> >("typedVar", python::class_<TypedVar, TypedVarPtr, python::bases<intBase> >("typedVar",
"Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance", "Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance",
python::no_init ) python::no_init )
.def( python::init<const TypeInfo&, ULONG64>() ) .def( python::init<const TypeInfoPtr&, ULONG64>() )
.def("getAddress", &TypedVar::getAddress, .def("getAddress", &TypedVar::getAddress,
"Return virtual address" ) "Return virtual address" )
.def("sizeof", &TypedVar::getSize, .def("sizeof", &TypedVar::getSize,

View File

@ -153,24 +153,16 @@ Module::reloadSymbols()
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
TypeInfo
Module::getTypeByName( const std::string &typeName )
{
return TypeInfo( getDia(), typeName );
}
///////////////////////////////////////////////////////////////////////////////////
TypedVar TypedVar
Module::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr ) Module::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr )
{ {
return TypedVar( TypeInfo( getDia(), typeName ), addr ); return TypedVar( getTypeByName(typeName), addr );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
TypedVar TypedVar
Module::getTypedVarByType( const TypeInfo &typeInfo, ULONG64 addr ) Module::getTypedVarByType( const TypeInfoPtr &typeInfo, ULONG64 addr )
{ {
return TypedVar( typeInfo, addr ); return TypedVar( typeInfo, addr );
} }
@ -182,7 +174,7 @@ Module::getTypedVarByName( const std::string &symName )
{ {
pyDia::SymbolPtr typeSym = getDia()->getChildByName( symName ); pyDia::SymbolPtr typeSym = getDia()->getChildByName( symName );
return TypedVar( TypeInfo( typeSym->getType() ), typeSym->getRva() + m_base ); return TypedVar( TypeInfo::getTypeInfo( typeSym->getType() ), typeSym->getRva() + m_base );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -201,7 +193,7 @@ Module::getTypedVarByAddr( ULONG64 addr )
if (displacement) if (displacement)
throw DbgException( "not exactly match by RVA" ); throw DbgException( "not exactly match by RVA" );
return TypedVar( TypeInfo( diaSym->getType() ), addr ); return TypedVar( TypeInfo::getTypeInfo( diaSym->getType() ), addr );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////

View File

@ -59,11 +59,13 @@ public:
return sym->getRva(); return sym->getRva();
} }
TypeInfo getTypeByName( const std::string &typeName ); TypeInfoPtr getTypeByName( const std::string &typeName ) {
return TypeInfo::getTypeInfo( boost::static_pointer_cast<pyDia::Symbol>( getDia() ), typeName);
}
TypedVar getTypedVarByTypeName( const std::string &typeName, ULONG64 addr ); TypedVar getTypedVarByTypeName( const std::string &typeName, ULONG64 addr );
TypedVar getTypedVarByType( const TypeInfo &typeInfo, ULONG64 addr ); TypedVar getTypedVarByType( const TypeInfoPtr &typeInfo, ULONG64 addr );
TypedVar getTypedVarByAddr( ULONG64 addr ); TypedVar getTypedVarByAddr( ULONG64 addr );
@ -71,7 +73,7 @@ public:
private: private:
pyDia::GlobalScopePtr getDia() { pyDia::GlobalScopePtr& getDia() {
if (!m_dia) if (!m_dia)
m_dia = pyDia::GlobalScope::loadPdb( getPdbName() ); m_dia = pyDia::GlobalScope::loadPdb( getPdbName() );
return m_dia; return m_dia;

View File

@ -48,18 +48,5 @@
#include <boost/python/module.hpp> #include <boost/python/module.hpp>
#pragma warning(pop) #pragma warning(pop)
namespace python = boost::python; namespace python = boost::python;
//
//#include <vector> #include <boost/regex.hpp>
//
//template <typename TElem>
//TElem *getVectorBuffer(std::vector<TElem> &vec)
//{
// return vec.size() ? &vec[0] : NULL;
//}
//template <typename TElem>
//const TElem *getVectorBuffer(const std::vector<TElem> &vec)
//{
// return vec.size() ? &vec[0] : NULL;
//}
//
//// TODO: reference additional headers your program requires here

View File

@ -7,22 +7,22 @@ namespace pykd {
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
TypedVar::TypedVar ( IDebugClient4 *client, const TypeInfo& typeInfo, ULONG64 offset ) : TypedVar::TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) :
DbgObject( client ), DbgObject( client ),
m_typeInfo( typeInfo ), m_typeInfo( typeInfo ),
m_offset( offset ) m_offset( offset )
{ {
m_size = m_typeInfo.getSize(); m_size = m_typeInfo->getSize();
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
TypedVar::TypedVar( const TypeInfo& typeInfo, ULONG64 offset ) : TypedVar::TypedVar( const TypeInfoPtr& typeInfo, ULONG64 offset ) :
DbgObject( g_dbgClient->client() ), DbgObject( g_dbgClient->client() ),
m_typeInfo( typeInfo ), m_typeInfo( typeInfo ),
m_offset( offset ) m_offset( offset )
{ {
m_size = m_typeInfo.getSize(); m_size = m_typeInfo->getSize();
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -30,25 +30,25 @@ TypedVar::TypedVar( const TypeInfo& typeInfo, ULONG64 offset ) :
TypedVarPtr TypedVarPtr
TypedVar::getField( const std::string &fieldName ) TypedVar::getField( const std::string &fieldName )
{ {
TypeInfo fieldType = m_typeInfo.getField( fieldName ); TypeInfoPtr fieldType = m_typeInfo->getField( fieldName );
TypedVarPtr tv; TypedVarPtr tv;
if ( fieldType.isBasicType() ) if ( fieldType->isBasicType() )
{ {
tv.reset( new BasicTypedVar( m_client, fieldType, m_offset + fieldType.getOffset() ) ); tv.reset( new BasicTypedVar( m_client, fieldType, m_offset + fieldType->getOffset() ) );
return tv; return tv;
} }
if ( fieldType.isPointer() ) if ( fieldType->isPointer() )
{ {
tv.reset( new PtrTypedVar( m_client, fieldType, m_offset + fieldType.getOffset() ) ); tv.reset( new PtrTypedVar( m_client, fieldType, m_offset + fieldType->getOffset() ) );
return tv; return tv;
} }
if ( fieldType.isUserDefined() ) if ( fieldType->isUserDefined() )
{ {
tv.reset( new TypedVar( m_client, fieldType, m_offset + fieldType.getOffset() ) ); tv.reset( new TypedVar( m_client, fieldType, m_offset + fieldType->getOffset() ) );
return tv; return tv;
} }

View File

@ -17,10 +17,10 @@ class TypedVar : public intBase, protected DbgObject {
public: public:
TypedVar ( const TypeInfo& typeInfo, ULONG64 offset ); TypedVar ( const TypeInfoPtr& typeInfo, ULONG64 offset );
TypedVar ( IDebugClient4 *client, const TypeInfo& typeInfo, ULONG64 offset ); TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset );
ULONG64 getAddress() const { ULONG64 getAddress() const {
return m_offset; return m_offset;
@ -31,10 +31,10 @@ public:
} }
ULONG getOffset() { ULONG getOffset() {
return m_typeInfo.getOffset(); return m_typeInfo->getOffset();
} }
TypeInfo TypeInfoPtr
getType() const { getType() const {
return m_typeInfo; return m_typeInfo;
} }
@ -55,7 +55,7 @@ protected:
throw DbgException("can not change"); throw DbgException("can not change");
} }
TypeInfo m_typeInfo; TypeInfoPtr m_typeInfo;
ULONG64 m_offset; ULONG64 m_offset;
@ -68,7 +68,7 @@ class BasicTypedVar : public TypedVar {
public: public:
BasicTypedVar ( IDebugClient4 *client, const TypeInfo& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} BasicTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){}
TypedVarPtr TypedVarPtr
virtual getField( const std::string &fieldName ) { virtual getField( const std::string &fieldName ) {
@ -89,7 +89,7 @@ class PtrTypedVar : public TypedVar {
public: public:
PtrTypedVar ( IDebugClient4 *client, const TypeInfo& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} PtrTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){}
TypedVarPtr TypedVarPtr
virtual getField( const std::string &fieldName ) { virtual getField( const std::string &fieldName ) {

View File

@ -4,90 +4,206 @@
namespace pykd { namespace pykd {
/////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
TypeInfo::TypeInfo( pyDia::GlobalScopePtr &diaScope, const std::string &symName ) : TypeInfoPtr TypeInfo::getTypeInfo( pyDia::SymbolPtr &typeSym )
m_offset( 0 )
{ {
pyDia::SymbolPtr typeSym = diaScope->getChildByName( symName ); ULONG tag = typeSym->getSymTag();
if ( typeSym->getSymTag() == SymTagData ) switch( typeSym->getSymTag() )
{ {
m_dia = typeSym->getType(); case SymTagBaseType:
} return getBaseTypeInfo( typeSym );
else
{ case SymTagUDT:
m_dia = typeSym; return TypeInfoPtr( new UdtTypeInfo( typeSym ) );
case SymTagArrayType:
return TypeInfoPtr( new ArrayTypeInfo( typeSym ) );
case SymTagPointerType:
return TypeInfoPtr( new PointerTypeInfo( typeSym ) );
} }
throw DbgException( "type name invalid" );
} }
/////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
std::string static const boost::regex arrayMatch("^(.*)\\[(\\d+)\\]$");
TypeInfo::getName()
TypeInfoPtr TypeInfo::getTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName )
{ {
std::stringstream sstr; size_t pos = symName.find_first_of( "*[" );
pyDia::SymbolPtr diaptr = m_dia; if ( pos == std::string::npos )
{
TypeInfoPtr basePtr = getBaseTypeInfo( symName );
if ( basePtr != 0 )
return basePtr;
pyDia::SymbolPtr typeSym = symScope->getChildByName( symName );
if ( typeSym->getSymTag() == SymTagData )
typeSym = typeSym->getType();
return getTypeInfo( typeSym );
}
int symtag = diaptr->getSymTag(); if ( symName[ symName.size() - 1 ] == '*' )
return TypeInfoPtr( new PointerTypeInfo( symScope,symName.substr( 0, symName.size() - 1 ) ) );
while( symtag == SymTagArrayType || symtag == SymTagPointerType ) boost::cmatch matchResult;
if ( boost::regex_match( symName.c_str(), matchResult, arrayMatch ) )
{ {
if ( symtag == SymTagArrayType ) std::string sym = std::string( matchResult[1].first, matchResult[1].second );
{
sstr << '[' << diaptr->getCount() << ']';
}
else
{
sstr << '*';
}
diaptr = diaptr->getType(); return TypeInfoPtr( new ArrayTypeInfo( symScope, sym, std::atoi( matchResult[2].first ) ) );
symtag = diaptr->getSymTag();
} }
std::string typeName = symtag == SymTagBaseType ?
diaptr->getBasicTypeName( diaptr->getBaseType() ) :
diaptr->getName();
typeName += sstr.str(); throw DbgException( "type name invalid" );
return typeName;
};
///////////////////////////////////////////////////////////////////////////////////
bool
TypeInfo::isBasicType()
{
return m_dia->getSymTag() == SymTagBaseType;
} }
/////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
bool static const boost::regex baseMatch("^(Char)|(WChar)|(Int2B)|(UInt2B)|(Int4B)|(UInt4B)|(Int8B)|(UInt8B)|(Long)|(ULong)|(Float)|(Bool)$" );
TypeInfo::isArrayType()
TypeInfoPtr
TypeInfo::getBaseTypeInfo( const std::string &symName )
{ {
return m_dia->getSymTag() == SymTagArrayType; boost::cmatch baseMatchResult;
if ( boost::regex_match( symName.c_str(), baseMatchResult, baseMatch ) )
{
if ( baseMatchResult[1].matched )
return TypeInfoPtr( new TypeInfoWrapper<char>("Char") );
if ( baseMatchResult[2].matched )
return TypeInfoPtr( new TypeInfoWrapper<wchar_t>("WChar") );
if ( baseMatchResult[3].matched )
return TypeInfoPtr( new TypeInfoWrapper<short>("Int2B") );
if ( baseMatchResult[4].matched )
return TypeInfoPtr( new TypeInfoWrapper<unsigned short>("UInt2B") );
if ( baseMatchResult[5].matched )
return TypeInfoPtr( new TypeInfoWrapper<long>("Int4B") );
if ( baseMatchResult[6].matched )
return TypeInfoPtr( new TypeInfoWrapper<unsigned long>("UInt4B") );
if ( baseMatchResult[7].matched )
return TypeInfoPtr( new TypeInfoWrapper<__int64>("Int8B") );
if ( baseMatchResult[8].matched )
return TypeInfoPtr( new TypeInfoWrapper<unsigned __int64>("UInt8B") );
if ( baseMatchResult[9].matched )
return TypeInfoPtr( new TypeInfoWrapper<long>("Long") );
if ( baseMatchResult[10].matched )
return TypeInfoPtr( new TypeInfoWrapper<unsigned long>("ULong") );
if ( baseMatchResult[11].matched )
return TypeInfoPtr( new TypeInfoWrapper<float>("Float") );
if ( baseMatchResult[12].matched )
return TypeInfoPtr( new TypeInfoWrapper<bool>("Bool") );
}
return TypeInfoPtr();
} }
/////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
bool TypeInfoPtr
TypeInfo::isPointer() TypeInfo::getBaseTypeInfo( pyDia::SymbolPtr &symbol )
{ {
return m_dia->getSymTag() == SymTagPointerType; std::string symName = symbol->getBasicTypeName( symbol->getBaseType() );
if ( symName == "Int" || symName == "UInt" )
{
std::stringstream sstr;
sstr << symName << symbol->getSize() << "B";
return getBaseTypeInfo( sstr.str() );
}
TypeInfoPtr ptr = getBaseTypeInfo( symName );
if ( ptr == 0 )
ptr = TypeInfoPtr( new BaseTypeInfo( symbol ) );
return ptr;
} }
/////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
bool PointerTypeInfo::PointerTypeInfo( pyDia::SymbolPtr &symbol )
TypeInfo::isUserDefined()
{ {
return m_dia->getSymTag() == SymTagUDT; m_derefType = TypeInfo::getTypeInfo( symbol->getType() );
m_size = (ULONG)symbol->getSize();
} }
/////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
PointerTypeInfo::PointerTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName )
{
m_derefType = TypeInfo::getTypeInfo( symScope, symName );
m_size = symScope->getMachineType() == CV_CFL_X64 ? 8 : 4;
}
/////////////////////////////////////////////////////////////////////////////////////
std::string PointerTypeInfo::getName()
{
return m_derefType->getName() + '*';
}
/////////////////////////////////////////////////////////////////////////////////////
ULONG PointerTypeInfo::getSize()
{
return m_size;
}
/////////////////////////////////////////////////////////////////////////////////////
ArrayTypeInfo::ArrayTypeInfo( pyDia::SymbolPtr &symbol )
{
m_derefType = TypeInfo::getTypeInfo( symbol->getType() );
m_count = symbol->getCount();
}
/////////////////////////////////////////////////////////////////////////////////////
ArrayTypeInfo::ArrayTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName, ULONG count )
{
m_derefType = TypeInfo::getTypeInfo( symScope, symName );
m_count = count;
}
/////////////////////////////////////////////////////////////////////////////////////
std::string ArrayTypeInfo::getName()
{
std::stringstream sstr;
sstr << m_derefType->getName() << '[' << m_count << ']';
return sstr.str();
}
/////////////////////////////////////////////////////////////////////////////////////
ULONG ArrayTypeInfo::getSize()
{
return m_derefType->getSize() * m_count;
}
/////////////////////////////////////////////////////////////////////////////////////
}; // end namespace pykd }; // end namespace pykd

View File

@ -8,57 +8,266 @@ namespace pykd {
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
class TypeInfo { class TypeInfo;
typedef boost::shared_ptr<TypeInfo> TypeInfoPtr;
///////////////////////////////////////////////////////////////////////////////////
class TypeInfo : boost::noncopyable {
public: public:
TypeInfo( pyDia::GlobalScopePtr &diaScope, const std::string &symName ); static
TypeInfoPtr getTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName );
TypeInfo( pyDia::SymbolPtr &diaType ) : static
m_offset( 0 ), TypeInfoPtr getTypeInfo( pyDia::SymbolPtr &symbol );
m_dia( diaType )
{}
TypeInfo static
getField( const std::string &fieldName ) { TypeInfoPtr getBaseTypeInfo( const std::string &name );
pyDia::SymbolPtr field = m_dia->getChildByName( fieldName );
TypeInfo ti( field->getType() ); static
ti.m_offset = field->getOffset(); TypeInfoPtr getBaseTypeInfo( pyDia::SymbolPtr &symbol );
return ti;
public:
virtual std::string getName() = 0;
virtual ULONG getSize() = 0;
virtual TypeInfoPtr getField( const std::string &fieldName ) = 0;
virtual bool isBasicType() {
return false;
} }
std::string virtual bool isPointer() {
getName(); return false;
}
ULONG virtual bool isUserDefined() {
getOffset() { return false;
}
ULONG getOffset() {
return m_offset; return m_offset;
} }
ULONG void setOffset( ULONG offset ) {
getSize() { m_offset = offset;
return (ULONG)m_dia->getSize(); }
}
bool protected:
isBasicType();
bool ULONG m_offset;
isArrayType();
bool
isPointer();
bool
isUserDefined();
private:
pyDia::SymbolPtr m_dia;
ULONG m_offset;
}; };
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
class BaseTypeInfo : public TypeInfo
{
public:
BaseTypeInfo( pyDia::SymbolPtr &symbol ) :
m_dia( symbol )
{}
protected:
virtual std::string getName() {
return m_dia->getBasicTypeName( m_dia->getBaseType() );
}
virtual ULONG getSize() {
return (ULONG)m_dia->getSize();
}
virtual TypeInfoPtr getField( const std::string &fieldName ) {
throw DbgException( "there is no such field" );
}
virtual bool isBasicType() {
return true;
}
pyDia::SymbolPtr m_dia;
};
///////////////////////////////////////////////////////////////////////////////////
template<typename T>
class TypeInfoWrapper : public TypeInfo
{
public:
TypeInfoWrapper( const std::string &name ) :
m_name(name)
{}
private:
virtual std::string getName() {
return m_name;
}
virtual ULONG getSize() {
return sizeof(T);
}
virtual TypeInfoPtr getField( const std::string &fieldName ) {
throw DbgException( "there is no such field" );
}
virtual bool isBasicType() {
return true;
}
std::string m_name;
};
///////////////////////////////////////////////////////////////////////////////////
class UdtTypeInfo : public BaseTypeInfo
{
public:
UdtTypeInfo ( pyDia::SymbolPtr &symbol ) :
BaseTypeInfo( symbol )
{}
virtual std::string getName() {
return m_dia->getName();
}
virtual TypeInfoPtr getField( const std::string &fieldName ) {
pyDia::SymbolPtr field = m_dia->getChildByName( fieldName );
TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, fieldName );
ti->setOffset( field->getOffset() );
return ti;
}
virtual bool isUserDefined() {
return true;
}
};
///////////////////////////////////////////////////////////////////////////////////
class PointerTypeInfo : public TypeInfo {
public:
PointerTypeInfo( pyDia::SymbolPtr &symbol );
PointerTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName );
virtual std::string getName();
virtual ULONG getSize();
virtual TypeInfoPtr getField( const std::string &fieldName ) {
throw DbgException( "there is no such field" );
}
virtual bool isPointer() {
return true;
}
private:
TypeInfoPtr m_derefType;
ULONG m_size;
};
///////////////////////////////////////////////////////////////////////////////////
class ArrayTypeInfo : public TypeInfo {
public:
ArrayTypeInfo( pyDia::SymbolPtr &symbol );
ArrayTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName, ULONG count );
virtual std::string getName();
virtual ULONG getSize();
virtual TypeInfoPtr getField( const std::string &fieldName ) {
throw DbgException( "there is no such field" );
}
private:
TypeInfoPtr m_derefType;
ULONG m_count;
};
///////////////////////////////////////////////////////////////////////////////////
//
//class TypeInfo {
//
//public:
//
// TypeInfo( pyDia::GlobalScopePtr &diaScope, const std::string &symName );
//
// TypeInfo( pyDia::SymbolPtr &diaType ) :
// m_offset( 0 ),
// m_dia( diaType )
// {}
//
// TypeInfo
// getField( const std::string &fieldName ) {
// pyDia::SymbolPtr field = m_dia->getChildByName( fieldName );
// TypeInfo ti( field->getType() );
// ti.m_offset = field->getOffset();
// return ti;
// }
//
// std::string
// getName();
//
// ULONG
// getOffset() {
// return m_offset;
// }
//
// ULONG
// getSize() {
// return (ULONG)m_dia->getSize();
// }
//
// bool
// isBasicType();
//
// bool
// isArrayType();
//
// bool
// isPointer();
//
// bool
// isUserDefined();
//
//private:
//
// pyDia::SymbolPtr m_dia;
//
// ULONG m_offset;
//
//};
///////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd }; // namespace pykd

View File

@ -52,6 +52,8 @@ if __name__ == "__main__":
target.module.reload(); target.module.reload();
suite = getTestSuite() suite = getTestSuite()
#suite = getTestSuite( "typedvar.TypedVarTest.testCtor" ) #suite = getTestSuite( "typeinfo.TypeInfoTest" )
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite ) unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite )
a = raw_input("\npress return\n")

View File

@ -15,29 +15,46 @@ class TypeInfoTest( unittest.TestCase ):
def testCreateByName( self ): def testCreateByName( self ):
""" creating typeInfo by the type name """ """ creating typeInfo by the type name """
ti1 = target.module.type( "structTest" ) #self.assertEqual( "structTest", target.module.type( "structTest" ).name() )
ti2 = target.module.type( "classChild" ) #self.assertEqual( "structTest**", target.module.type( "structTest**" ).name() )
self.assertEqual( "Int4B[2][3]", target.module.type("Int4B[2][3]").name() )
def testGetField( self ): def testGetField( self ):
""" get field of the complex type """ """ get field of the complex type """
ti1 = target.module.type( "structTest" ) ti1 = target.module.type( "structTest" )
self.assertTrue( hasattr( ti1, "m_field0" ) ) self.assertTrue( hasattr( ti1, "m_field0" ) )
try: hasattr(ti1, "m_field4" ) # non-exsisting field try: hasattr(ti1, "m_field4" ) # non-exsisting field
except pykd.DiaException: pass except pykd.BaseException: pass
def testBaseTypes( self ):
self.assertEqual( 1, target.module.type("Char").size() )
self.assertEqual( 2, target.module.type("WChar").size() )
self.assertEqual( 2, target.module.type("Int2B").size() )
self.assertEqual( 2, target.module.type("UInt2B").size() )
self.assertEqual( 4, target.module.type("Int4B").size() )
self.assertEqual( 4, target.module.type("UInt4B").size() )
self.assertEqual( 8, target.module.type("Int8B").size() )
self.assertEqual( 8, target.module.type("UInt8B").size() )
def testName( self ): def testName( self ):
ti1 = target.module.type( "classChild" ) ti1 = target.module.type( "classChild" )
self.assertEqual( "classChild", ti1.name() ) self.assertEqual( "classChild", ti1.name() )
self.assertEqual( "Int", ti1.m_childField.name() ) self.assertEqual( "Int4B", ti1.m_childField.name() )
self.assertEqual( "structTest", ti1.m_childField3.name() ) self.assertEqual( "structTest", ti1.m_childField3.name() )
self.assertEqual( "structTest", target.module.type("g_structTest").name() ) self.assertEqual( "structTest", target.module.type("g_structTest").name() )
def testArrayName( self ):
self.assertEqual( "structTest[2]", target.module.type("g_testArray").name() )
def testPtrName( self ): def testPtrName( self ):
self.assertEqual( "structTest*", target.module.type("g_structTestPtr").name() ) self.assertEqual( "structTest*", target.module.type("g_structTestPtr").name() )
self.assertEqual( "structTest**", target.module.type("g_structTestPtrPtr").name() ) self.assertEqual( "structTest**", target.module.type("g_structTestPtrPtr").name() )
self.assertEqual( "structTest**", target.module.type("structTest**").name() )
def testArrayName( self ):
self.assertEqual( "structTest[2]", target.module.type("g_testArray").name() )
self.assertEqual( "Int4B[2][3]", target.module.type("intMatrix").name() )
self.assertEqual( "Char*[2]", target.module.type("strArray").name() )
self.assertEqual( "Int4B[2][3]*",target.module.type("ptrIntMatrix").name() )
self.assertEqual( "Char*[2]*", target.module.type("ptrStrArray").name() )
self.assertEqual( "Int4B[2][3]", target.module.type("Int[2][3]").name() )
def testOffset( self ): def testOffset( self ):
ti1 = target.module.type( "structTest" ) ti1 = target.module.type( "structTest" )
@ -49,4 +66,5 @@ class TypeInfoTest( unittest.TestCase ):
def testSize( self ): def testSize( self ):
ti1 = target.module.type( "structTest" ) ti1 = target.module.type( "structTest" )
self.assertEqual( 20, ti1.size() ) self.assertEqual( 20, ti1.size() )
self.assertEqual( pykd.ptrSize(), target.module.type("structTest**").size() )

View File

@ -64,6 +64,11 @@ unsigned short ushortArray[] = {0, 10, 0xFF, 0x8000, 0xFFFF };
unsigned long ulongArray[] = {0, 0xFF, 0x8000, 0x80000000, 0xFFFFFFFF }; unsigned long ulongArray[] = {0, 0xFF, 0x8000, 0x80000000, 0xFFFFFFFF };
unsigned __int64 ulonglongArray[] = {0, 0xFF, 0xFFFFFFFF, 0x8000000000000000, 0xFFFFFFFFFFFFFFFF }; unsigned __int64 ulonglongArray[] = {0, 0xFF, 0xFFFFFFFF, 0x8000000000000000, 0xFFFFFFFFFFFFFFFF };
int intMatrix[2][3] = { { 0, 1, 2}, { 3, 4, 5 } };
char* strArray[] = { "hello", "bye" };
int (*ptrIntMatrix)[2][3] = &intMatrix;
char *(*ptrStrArray)[2] = &strArray;
class classChild : public classBase { class classChild : public classBase {
public: public:
int m_childField; int m_childField;
@ -105,6 +110,10 @@ void FuncWithName0()
std::cout << ushortArray[2]; std::cout << ushortArray[2];
std::cout << ulongArray[2]; std::cout << ulongArray[2];
std::cout << ulonglongArray[2]; std::cout << ulonglongArray[2];
std::cout << intMatrix[1][1];
std::cout << strArray[0];
std::cout << (*ptrIntMatrix)[0][1];
} }
void FuncWithName1(int a) void FuncWithName1(int a)