mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[0.2.x] + custom types
git-svn-id: https://pykd.svn.codeplex.com/svn@79382 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
77b1eee2f4
commit
70747aac37
98
pykd/customtypes.cpp
Normal file
98
pykd/customtypes.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "customtypes.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace pykd {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypeInfoPtr CustomStruct::create(const std::string &name, ULONG alignReq /*= 0*/)
|
||||
{
|
||||
return TypeInfoPtr( new CustomStruct(name, alignReq) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG CustomStruct::getSize()
|
||||
{
|
||||
if (UdtFieldColl::empty())
|
||||
return 0;
|
||||
|
||||
UdtUtils::Field &field = UdtFieldColl::last();
|
||||
return field.m_offset + field.m_type->getSize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
|
||||
{
|
||||
bool fieldExist = false;
|
||||
try
|
||||
{
|
||||
lookupField(fieldName);
|
||||
fieldExist = true;
|
||||
}
|
||||
catch (const TypeException &except)
|
||||
{
|
||||
DBG_UNREFERENCED_PARAMETER(except);
|
||||
}
|
||||
if (fieldExist)
|
||||
throw TypeException(getName(), "duplicate field name: " + fieldName);
|
||||
|
||||
ULONG offset = getSize();
|
||||
offset += (offset % m_alignReq);
|
||||
UdtFieldColl::push_back(
|
||||
UdtUtils::Field(offset, fieldName, fieldType)
|
||||
);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypeInfoPtr CustomUnion::create(const std::string &name)
|
||||
{
|
||||
return TypeInfoPtr( new CustomUnion(name) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG CustomUnion::getSize()
|
||||
{
|
||||
ULONG size = 0;
|
||||
for (ULONG i = 0; i < getFieldCount(); ++i)
|
||||
{
|
||||
ULONG fieldSize = lookupField(i).m_type->getSize();
|
||||
if (fieldSize > size)
|
||||
size = fieldSize;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CustomUnion::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
|
||||
{
|
||||
bool fieldExist = false;
|
||||
try
|
||||
{
|
||||
lookupField(fieldName);
|
||||
fieldExist = true;
|
||||
}
|
||||
catch (const TypeException &except)
|
||||
{
|
||||
DBG_UNREFERENCED_PARAMETER(except);
|
||||
}
|
||||
if (fieldExist)
|
||||
throw TypeException(getName(), "duplicate field name: " + fieldName);
|
||||
|
||||
UdtFieldColl::push_back(
|
||||
UdtUtils::Field(0, fieldName, fieldType)
|
||||
);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace pykd
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
69
pykd/customtypes.h
Normal file
69
pykd/customtypes.h
Normal file
@ -0,0 +1,69 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "typeinfo.h"
|
||||
#include "win\dbgeng.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace pykd {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CustomStruct : public UdtFieldColl
|
||||
{
|
||||
public:
|
||||
static TypeInfoPtr create(const std::string &name, ULONG alignReq = 0);
|
||||
|
||||
protected:
|
||||
CustomStruct(const std::string &name, ULONG alignReq)
|
||||
: UdtFieldColl(name), m_name(name), m_alignReq(alignReq ? alignReq : ptrSize())
|
||||
{
|
||||
}
|
||||
|
||||
virtual std::string getName() override {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
virtual ULONG getSize() override;
|
||||
|
||||
virtual void appendField(const std::string &fieldName, TypeInfoPtr fieldType) override;
|
||||
|
||||
virtual std::string getTypeString() const override {
|
||||
return "custom struct";
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
ULONG m_alignReq;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CustomUnion : public UdtFieldColl
|
||||
{
|
||||
public:
|
||||
static TypeInfoPtr create(const std::string &name);
|
||||
|
||||
protected:
|
||||
CustomUnion(const std::string &name) : UdtFieldColl(name) {}
|
||||
|
||||
virtual ULONG getSize() override;
|
||||
|
||||
virtual void appendField(const std::string &fieldName, TypeInfoPtr fieldType) override;
|
||||
|
||||
virtual std::string getTypeString() const override {
|
||||
return "custom union";
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace pykd
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
@ -361,6 +361,10 @@
|
||||
RelativePath=".\cpureg.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\customtypes.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dbgexcept.cpp"
|
||||
>
|
||||
@ -467,6 +471,10 @@
|
||||
RelativePath=".\cpureg.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\customtypes.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dbgengine.h"
|
||||
>
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "dbgexcept.h"
|
||||
#include "dbgmem.h"
|
||||
#include "typeinfo.h"
|
||||
#include "customtypes.h"
|
||||
#include "typedvar.h"
|
||||
#include "cpureg.h"
|
||||
#include "disasm.h"
|
||||
@ -59,6 +60,8 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceFile_, getSourceFile, 0, 1 );
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( setSoftwareBp_, setSoftwareBp, 1, 2 );
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( setHardwareBp_, setHardwareBp, 3, 4 );
|
||||
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( CustomStruct_create, CustomStruct::create, 1, 2 );
|
||||
|
||||
BOOST_PYTHON_MODULE( pykd )
|
||||
{
|
||||
python::scope().attr("version") = pykdVersion;
|
||||
@ -231,6 +234,12 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
python::def( "removeAllBp", &breakPointRemoveAll,
|
||||
"Remove all breapoints" );
|
||||
|
||||
// custom types
|
||||
python::def( "createStruct", &CustomStruct::create, CustomStruct_create( python::args( "name", "alignReq" ),
|
||||
"Create empty structure. Use append() method for building" ) );
|
||||
python::def( "createUnion", &CustomUnion::create,
|
||||
"Create empty union. Use append() method for building" );
|
||||
|
||||
python::class_<intBase>( "intBase", "intBase", python::no_init )
|
||||
.def( python::init<python::object&>() )
|
||||
.def( "__eq__", &intBase::eq )
|
||||
@ -334,6 +343,7 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
.def( "field", &TypeInfo::getField )
|
||||
.def( "asMap", &TypeInfo::asMap )
|
||||
.def( "deref", &TypeInfo::deref )
|
||||
.def( "append", &TypeInfo::appendField )
|
||||
.def( "__str__", &TypeInfo::print )
|
||||
.def( "__getattr__", &TypeInfo::getField )
|
||||
.def("__len__", &TypeInfo::getElementCount )
|
||||
|
@ -557,10 +557,45 @@ ULONG64 TypeInfo::getStaticOffset()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG UdtTypeInfo::getFieldCount()
|
||||
std::string UdtFieldColl::print()
|
||||
{
|
||||
refreshFields();
|
||||
return (ULONG)m_fields.size();
|
||||
std::stringstream sstr;
|
||||
|
||||
sstr << getTypeString() << ": " << getName() << " Size: 0x" << std::hex << getSize() << " (" << std::dec << getSize() << ")" << std::endl;
|
||||
|
||||
ULONG fieldCount = getFieldCount();
|
||||
|
||||
for ( ULONG i = 0; i < fieldCount; ++i )
|
||||
{
|
||||
const UdtUtils::Field &udtField = lookupField(i);
|
||||
TypeInfoPtr fieldType = udtField.m_type;
|
||||
|
||||
if ( fieldType->isStaticMember() )
|
||||
{
|
||||
sstr << " =" << std::right << std::setw(10) << std::setfill('0') << std::hex << fieldType->getStaticOffset();
|
||||
sstr << " " << std::left << std::setw(18) << std::setfill(' ') << udtField.m_name << ':';
|
||||
}
|
||||
else
|
||||
if ( fieldType->isVirtualMember() )
|
||||
{
|
||||
ULONG virtualBasePtr, virtualDispIndex, virtualDispSize;
|
||||
fieldType->getVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize );
|
||||
|
||||
sstr << " virtual base " << fieldType->getVirtualBase()->getName();
|
||||
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << udtField.m_offset;
|
||||
sstr << " " << udtField.m_name << ':';
|
||||
}
|
||||
else
|
||||
{
|
||||
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << udtField.m_offset;
|
||||
sstr << " " << std::left << std::setw(24) << std::setfill(' ') << udtField.m_name << ':';
|
||||
}
|
||||
|
||||
sstr << " " << std::left << fieldType->getName();
|
||||
sstr << std::endl;
|
||||
}
|
||||
|
||||
return sstr.str();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -615,7 +650,9 @@ void UdtTypeInfo::getFields(
|
||||
break;
|
||||
}
|
||||
|
||||
m_fields.push_back( UdtUtils::Field( fieldOffset, childSym->getName(), ti ) );
|
||||
UdtFieldColl::push_back(
|
||||
UdtUtils::Field( fieldOffset, childSym->getName(), ti )
|
||||
);
|
||||
}
|
||||
else
|
||||
if ( symTag == SymTagVTable )
|
||||
@ -632,7 +669,7 @@ void UdtTypeInfo::getFields(
|
||||
|
||||
}
|
||||
|
||||
m_fields.push_back(
|
||||
UdtFieldColl::push_back(
|
||||
UdtUtils::Field( startOffset + childSym->getOffset(), "__VFN_table", ti )
|
||||
);
|
||||
}
|
||||
@ -666,7 +703,7 @@ void UdtTypeInfo::getVirtualFields()
|
||||
|
||||
void UdtTypeInfo::refreshFields()
|
||||
{
|
||||
if ( m_fields.empty() )
|
||||
if ( UdtFieldColl::empty() )
|
||||
{
|
||||
getFields( m_dia, SymbolPtr() );
|
||||
getVirtualFields();
|
||||
@ -675,49 +712,6 @@ void UdtTypeInfo::refreshFields()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string UdtTypeInfo::print()
|
||||
{
|
||||
std::stringstream sstr;
|
||||
|
||||
sstr << "struct/class: " << getName() << " Size: 0x" << std::hex << getSize() << " (" << std::dec << getSize() << ")" << std::endl;
|
||||
|
||||
ULONG fieldCount = getFieldCount();
|
||||
|
||||
for ( ULONG i = 0; i < fieldCount; ++i )
|
||||
{
|
||||
const UdtUtils::Field &udtField = lookupField(i);
|
||||
TypeInfoPtr fieldType = udtField.m_type;
|
||||
|
||||
if ( fieldType->isStaticMember() )
|
||||
{
|
||||
sstr << " =" << std::right << std::setw(10) << std::setfill('0') << std::hex << fieldType->getStaticOffset();
|
||||
sstr << " " << std::left << std::setw(18) << std::setfill(' ') << udtField.m_name << ':';
|
||||
}
|
||||
else
|
||||
if ( fieldType->isVirtualMember() )
|
||||
{
|
||||
ULONG virtualBasePtr, virtualDispIndex, virtualDispSize;
|
||||
fieldType->getVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize );
|
||||
|
||||
sstr << " virtual base " << fieldType->getVirtualBase()->getName();
|
||||
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << udtField.m_offset;
|
||||
sstr << " " << udtField.m_name << ':';
|
||||
}
|
||||
else
|
||||
{
|
||||
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << udtField.m_offset;
|
||||
sstr << " " << std::left << std::setw(24) << std::setfill(' ') << udtField.m_name << ':';
|
||||
}
|
||||
|
||||
sstr << " " << std::left << fieldType->getName();
|
||||
sstr << std::endl;
|
||||
}
|
||||
|
||||
return sstr.str();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypeInfoPtr EnumTypeInfo::getField( const std::string &fieldName )
|
||||
{
|
||||
return TypeInfo::getTypeInfo( m_dia, fieldName );
|
||||
|
@ -157,6 +157,10 @@ public:
|
||||
throw PyException( PyExc_TypeError, "object is unsubscriptable");
|
||||
}
|
||||
|
||||
virtual void appendField(const std::string &fieldName, TypeInfoPtr fieldType) {
|
||||
throw TypeException( getName(), "type is not is not extensible" );
|
||||
}
|
||||
|
||||
void setConstant( const BaseTypeVariant& var )
|
||||
{
|
||||
m_constant = true;
|
||||
@ -298,24 +302,11 @@ private:
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class UdtTypeInfo : public TypeInfo
|
||||
class UdtFieldColl : public TypeInfo
|
||||
{
|
||||
public:
|
||||
|
||||
UdtTypeInfo (SymbolPtr &symbol ) :
|
||||
m_dia( symbol ),
|
||||
m_fields( symbol->getName() )
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual std::string getName() {
|
||||
return m_dia->getName();
|
||||
}
|
||||
|
||||
virtual ULONG getSize() {
|
||||
return (ULONG)m_dia->getSize();
|
||||
return m_fields.getName();
|
||||
}
|
||||
|
||||
virtual TypeInfoPtr getField( const std::string &fieldName ) {
|
||||
@ -331,7 +322,7 @@ protected:
|
||||
}
|
||||
|
||||
virtual ULONG getFieldOffsetByNameRecirsive( const std::string &fieldName ) {
|
||||
return UdtUtils::getFiledOffsetRecirsive( shared_from_this(), fieldName );
|
||||
return UdtUtils::getFieldOffsetRecirsive( shared_from_this(), fieldName );
|
||||
}
|
||||
|
||||
virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) {
|
||||
@ -342,10 +333,9 @@ protected:
|
||||
return lookupField(index).m_offset;
|
||||
}
|
||||
|
||||
virtual ULONG getFieldCount();
|
||||
|
||||
virtual bool isUserDefined() {
|
||||
return true;
|
||||
virtual ULONG getFieldCount() {
|
||||
refreshFields();
|
||||
return (ULONG)m_fields.size();
|
||||
}
|
||||
|
||||
virtual ULONG getElementCount() {
|
||||
@ -358,9 +348,61 @@ protected:
|
||||
|
||||
virtual std::string print();
|
||||
|
||||
SymbolPtr m_dia;
|
||||
virtual bool isUserDefined() {
|
||||
return true;
|
||||
}
|
||||
|
||||
UdtUtils::FieldCollection m_fields;
|
||||
protected:
|
||||
UdtFieldColl(const std::string &typeName) : m_fields(typeName) {}
|
||||
|
||||
virtual void refreshFields() {}
|
||||
virtual std::string getTypeString() const = 0;
|
||||
|
||||
bool empty() const {
|
||||
return m_fields.empty();
|
||||
}
|
||||
|
||||
void push_back(const UdtUtils::Field &field) {
|
||||
m_fields.push_back(field);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const UdtUtils::Field &lookupField( T index) {
|
||||
refreshFields();
|
||||
return m_fields.lookup(index);
|
||||
}
|
||||
|
||||
UdtUtils::Field &last(){
|
||||
return *m_fields.rbegin();
|
||||
}
|
||||
|
||||
private:
|
||||
UdtUtils::FieldCollection m_fields;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class UdtTypeInfo : public UdtFieldColl
|
||||
{
|
||||
public:
|
||||
|
||||
UdtTypeInfo (SymbolPtr &symbol ) :
|
||||
UdtFieldColl( symbol->getName() ),
|
||||
m_dia( symbol )
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ULONG getSize() {
|
||||
return (ULONG)m_dia->getSize();
|
||||
}
|
||||
void getVirtualFields();
|
||||
|
||||
virtual void refreshFields() override;
|
||||
|
||||
virtual std::string getTypeString() const override {
|
||||
return "struct/class";
|
||||
}
|
||||
|
||||
void getFields(
|
||||
SymbolPtr &rootSym,
|
||||
@ -371,16 +413,8 @@ protected:
|
||||
ULONG m_virtualDispSize = 0 );
|
||||
|
||||
|
||||
void getVirtualFields();
|
||||
|
||||
private:
|
||||
void refreshFields();
|
||||
|
||||
template <typename T>
|
||||
const UdtUtils::Field &lookupField( T index) {
|
||||
refreshFields();
|
||||
return m_fields.lookup(index);
|
||||
}
|
||||
SymbolPtr m_dia;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -36,7 +36,7 @@ const Field &FieldCollection::lookup(const std::string &name) const
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG getFiledOffsetRecirsive(TypeInfoPtr typeInfo, const std::string &fieldName)
|
||||
ULONG getFieldOffsetRecirsive(TypeInfoPtr typeInfo, const std::string &fieldName)
|
||||
{
|
||||
// "m_field1.m_field2" -> ["m_field1", "m_field2"]
|
||||
typedef boost::char_separator<char> CharSep;
|
||||
|
@ -46,13 +46,17 @@ public:
|
||||
const Field &lookup(ULONG index) const;
|
||||
const Field &lookup(const std::string &name) const;
|
||||
|
||||
const std::string &getName() const {
|
||||
return m_baseTypeName;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_baseTypeName;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG getFiledOffsetRecirsive(TypeInfoPtr typeInfo, const std::string &fieldName);
|
||||
ULONG getFieldOffsetRecirsive(TypeInfoPtr typeInfo, const std::string &fieldName);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
72
test/scripts/customtypestest.py
Normal file
72
test/scripts/customtypestest.py
Normal file
@ -0,0 +1,72 @@
|
||||
"""Custom types tests"""
|
||||
|
||||
import unittest
|
||||
import target
|
||||
import pykd
|
||||
|
||||
class CustomTypesTest(unittest.TestCase):
|
||||
def testCommonStruct(self):
|
||||
mySubStruct = pykd.createStruct("MySubCustomStruct")
|
||||
mySubStruct.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
mySubStruct.append( "m_uint2", pykd.typeInfo("UInt2B") )
|
||||
|
||||
mySubUnion = pykd.createUnion("MySubCustomUnion")
|
||||
mySubUnion.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
mySubUnion.append( "m_uint2", pykd.typeInfo("UInt2B") )
|
||||
|
||||
myType = pykd.createStruct("MyCustomStruct")
|
||||
myType.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
myType.append( "m_uint4", pykd.typeInfo("UInt4B") )
|
||||
myType.append( "m_uint2", pykd.typeInfo("UInt2B") )
|
||||
myType.append( "m_struct", mySubStruct )
|
||||
myType.append( "m_union", mySubUnion )
|
||||
myType.append( "m_uint8", pykd.typeInfo("UInt8B") )
|
||||
|
||||
self.assertTrue( myType.size() != 0 )
|
||||
self.assertTrue( myType.size() >= myType.fieldOffset("m_uint8") + myType.m_uint8.size() )
|
||||
|
||||
self.assertTrue( myType.fieldOffset("m_uint1") == 0 )
|
||||
|
||||
self.assertTrue( myType.fieldOffset("m_uint1") < myType.fieldOffset("m_uint4") )
|
||||
self.assertTrue( myType.fieldOffset("m_uint1") + myType.m_uint1.size() <= myType.fieldOffset("m_uint4") )
|
||||
|
||||
self.assertTrue( myType.fieldOffset("m_uint4") < myType.fieldOffset("m_uint2") )
|
||||
self.assertTrue( myType.fieldOffset("m_uint4") + myType.m_uint4.size() <= myType.fieldOffset("m_uint2") )
|
||||
|
||||
self.assertTrue( myType.fieldOffset("m_uint2") < myType.fieldOffset("m_struct") )
|
||||
self.assertTrue( myType.fieldOffset("m_uint2") + myType.m_uint2.size() <= myType.fieldOffset("m_struct") )
|
||||
|
||||
self.assertTrue( myType.fieldOffset("m_struct") < myType.fieldOffset("m_union") )
|
||||
self.assertTrue( myType.fieldOffset("m_struct") + myType.m_struct.size() <= myType.fieldOffset("m_union") )
|
||||
|
||||
# print myType
|
||||
|
||||
def testCommonUnion(self):
|
||||
myType = pykd.createUnion("MyCustomStruct")
|
||||
myType.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
myType.append( "m_uint4", pykd.typeInfo("UInt4B") )
|
||||
myType.append( "m_uint2", pykd.typeInfo("UInt2B") )
|
||||
|
||||
self.assertFalse( myType.size() == 0 )
|
||||
self.assertTrue( myType.fieldOffset("m_uint1") == 0 )
|
||||
self.assertTrue( myType.fieldOffset("m_uint4") == 0 )
|
||||
self.assertTrue( myType.fieldOffset("m_uint2") == 0 )
|
||||
|
||||
def testDupFieldName(self):
|
||||
myType = pykd.createStruct("MyCustomStruct")
|
||||
exceptionRised = False
|
||||
myType.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
try:
|
||||
myType.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
except pykd.TypeException:
|
||||
exceptionRised = True
|
||||
self.assertTrue(exceptionRised)
|
||||
|
||||
myType = pykd.createUnion("MyCustomStruct")
|
||||
exceptionRised = False
|
||||
myType.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
try:
|
||||
myType.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
except pykd.TypeException:
|
||||
exceptionRised = True
|
||||
self.assertTrue(exceptionRised)
|
@ -20,6 +20,7 @@ import typeinfo
|
||||
import typedvar
|
||||
import regtest
|
||||
import localstest
|
||||
import customtypestest
|
||||
|
||||
class StartProcessWithoutParamsTest(unittest.TestCase):
|
||||
def testStart(self):
|
||||
@ -45,6 +46,7 @@ def getTestSuite( singleName = "" ):
|
||||
unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( customtypestest.CustomTypesTest ),
|
||||
# ^^^
|
||||
unittest.TestLoader().loadTestsFromTestCase( TerminateProcessTest ),
|
||||
|
||||
|
@ -408,6 +408,10 @@
|
||||
RelativePath="..\scripts\clienttest.py"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scripts\customtypestest.py"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scripts\dbgcmd.py"
|
||||
>
|
||||
|
Loading…
Reference in New Issue
Block a user