typeinfo.py 17.8 KB
Newer Older
1
#
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
#
#

import unittest
import target
import pykd

class TypeInfoTest( unittest.TestCase ):

    def testCtor( self ):
        self.assertEqual( "structTest", pykd.typeInfo( "structTest" ).name() )
        self.assertEqual( "structTest", pykd.typeInfo( target.moduleName + "!structTest" ).name() )
        self.assertEqual( "structTest", pykd.typeInfo( "g_structTest" ).name() )
        self.assertEqual( "structTest", pykd.typeInfo( target.moduleName + "!g_structTest" ).name() )     
        self.assertEqual( "Int1B", pykd.typeInfo( "Int1B" ).name() )	
 
    def testCreateByName( self ):
        """ creating typeInfo by the type name """
        self.assertEqual( "Int4B*", target.module.type("Int4B*").name() )
        self.assertEqual( "structTest", target.module.type( "structTest" ).name() )
        self.assertEqual( "structTest**", target.module.type( "structTest**" ).name() )
        self.assertEqual( "Int4B[2][3]", target.module.type("Int4B[2][3]").name() )
        self.assertEqual( "Int4B(*[4])[2][3]", target.module.type("Int4B(*[4])[2][3]").name() )
        self.assertEqual( "Int4B(*)[2][3]", target.module.type("Int4B((*))[2][3]").name() )
        self.assertEqual( "Int4B*", pykd.typeInfo("Int4B*").name() )

    def testCreateBySymbol(self):
        """ creating typeInfo by the symbol name """
        self.assertEqual( "structTest[2]", target.module.type("g_testArray").name() )
        self.assertEqual( "Int4B[2][3]", target.module.type("intMatrix").name() )
        self.assertEqual( "structTest*", target.module.type("g_structTestPtr").name() )
        self.assertEqual( "structTest**", target.module.type("g_structTestPtrPtr").name() )
        self.assertEqual( "Char*[2]", target.module.type("strArray").name() )
        self.assertEqual( "Char*(*)[2]", target.module.type("ptrStrArray").name() )
        self.assertEqual( "Int4B(*[4])[2][3]", target.module.type("arrIntMatrixPtrs").name() )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
37
        self.assertEqual( "Int4B(*)[2][3]", target.module.type("ptrIntMatrix").name() )
38 39 40 41

    def testGetField( self ):
        """ get field of the complex type """
        ti1 = target.module.type( "structTest" )
42
        self.assertTrue( "UInt4B", ti1.m_field0.name() )
ussrhero's avatar
ussrhero committed
43 44
        self.assertTrue( "m_field0" in ti1 )
        self.assertFalse( "not_exist" in ti1) # non-exsisting field
45
        self.assertRaises( pykd.SymbolException, lambda t: t.not_exists, ti1) # non-exsisting field
46 47


48
    def testBaseTypes( self ):
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
        self.assertEqual("Int1B", pykd.typeInfo( "Int1B" ).name() )
        self.assertEqual("Int2B", pykd.typeInfo( "Int2B" ).name() )
        self.assertEqual("Int4B", pykd.typeInfo( "Int4B" ).name() )
        self.assertEqual("Int8B", pykd.typeInfo( "Int8B" ).name() )
        self.assertEqual("UInt1B", pykd.typeInfo( "UInt1B" ).name() )
        self.assertEqual("UInt2B", pykd.typeInfo( "UInt2B" ).name() )
        self.assertEqual("UInt4B", pykd.typeInfo( "UInt4B" ).name() )
        self.assertEqual("UInt8B", pykd.typeInfo( "UInt8B" ).name() )

        self.assertEqual("Long", pykd.typeInfo( "Long" ).name() )
        self.assertEqual("ULong", pykd.typeInfo( "ULong" ).name() )
        self.assertEqual("Bool", pykd.typeInfo( "Bool" ).name() )
        self.assertEqual("Char", pykd.typeInfo("Char").name() )
        self.assertEqual("WChar", pykd.typeInfo("WChar").name() )

        self.assertEqual( 1, pykd.typeInfo("Int1B").size() )
        self.assertEqual( 1, pykd.typeInfo("UInt1B").size() )
        self.assertEqual( 2, pykd.typeInfo("Int2B").size() )
        self.assertEqual( 2, pykd.typeInfo("UInt2B").size() )
        self.assertEqual( 4, pykd.typeInfo("Int4B").size() )
        self.assertEqual( 4, pykd.typeInfo("UInt4B").size() )
        self.assertEqual( 8, pykd.typeInfo("Int8B").size() )
        self.assertEqual( 8, pykd.typeInfo("UInt8B").size() )

        self.assertEqual( 4, pykd.typeInfo("Long" ).size() )
        self.assertEqual( 4, pykd.typeInfo("ULong" ).size() )
        self.assertEqual( 1, pykd.typeInfo("Bool" ).size() )
        self.assertEqual( 1, pykd.typeInfo("Char").size() )
        self.assertEqual( 2, pykd.typeInfo("WChar").size() )
78 79

        try:
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
80
            self.assertEqual("Int9B", pykd.typeInfo( "Int9B" ).name() )
81 82 83 84
        except pykd.SymbolException:
            pass
            
    def testBaseTypePtr(self):
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
85 86
        self.assertEqual("Int1B*", pykd.typeInfo( "Int1B*" ).name() )
        self.assertEqual("Int1B", pykd.typeInfo( "Int1B*" ).deref().name() )
87 88
        
    def testBaseTypeArray(self):
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
89
        self.assertEqual("Int4B[20]", pykd.typeInfo( "Int4B[20]" ).name() )
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109

    def testName( self ):
        ti1 = target.module.type( "classChild" )
        self.assertEqual( "classChild", ti1.name() )
        self.assertEqual( "Int4B", ti1.m_childField.name() )
        self.assertEqual( "structTest", ti1.m_childField3.name() )
        self.assertEqual( "structTest", target.module.type("g_structTest").name() )
        
    def testVarName( self ):
        self.assertEqual( "structTest", target.module.type( "g_structTest").name() )
        self.assertRaises( pykd.TypeException, target.module.type, "g_testArray[0]" )
        self.assertRaises( pykd.TypeException, target.module.type, "*g_structTestPtr" )

    def testOffset( self ):
        ti1 = target.module.type( "structTest" )
        self.assertEqual( 0, ti1.fieldOffset("m_field0") )
        self.assertEqual( 4, ti1.fieldOffset("m_field1") )
        self.assertEqual( 12, ti1.fieldOffset("m_field2") )
        self.assertEqual( 14, ti1.fieldOffset("m_field3") )

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
110 111 112 113 114 115
        ti2 = target.module.type( "unionTest" )
        self.assertEqual( 0, ti2.fieldOffset("m_value") )
        self.assertEqual( 0, ti2.fieldOffset("m_structValue") )

        ti3 = target.module.type( "structWithNested" )
        self.assertEqual( ti3.fieldOffset( "m_unnameStruct"), ti3.fieldOffset( "m_unnameStruct.m_field2" ) )
116 117 118 119 120 121 122

    def testSize( self ):
        ti1 = target.module.type( "structTest" )
        self.assertEqual( 16 + pykd.ptrSize(), ti1.size() )
        self.assertEqual( pykd.ptrSize(), target.module.type("structTest**").size() )
        self.assertEqual( pykd.sizeof("structTest"), target.module.type("structTest").size() )
        self.assertEqual( pykd.sizeof("structTest**"), target.module.type("structTest**").size() )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
123
        self.assertEqual( pykd.sizeof("Int1B"), pykd.typeInfo("Int1B").size() )
124 125 126 127 128

    def testBitField( self ):
        ti = target.module.type( "g_structWithBits" )
        self.assertEqual( 0, ti.fieldOffset("m_bit6_8") )
        self.assertEqual( 4, ti.m_bit6_8.size() )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
129
        self.assertEqual( "UInt4B:3", ti.m_bit6_8.name() )
130 131 132 133 134 135 136 137 138 139 140 141
        self.assertEqual( 3, ti.m_bit6_8.bitWidth() )
        self.assertEqual( 6, ti.m_bit6_8.bitOffset() )

    def testEnum(self):
        ti = target.module.type("enumType")
        self.assertTrue( hasattr( ti, "TWO" ) )
        self.assertEqual( 4, ti.TWO.size() )

        ti = target.module.type("classChild")
        self.assertEqual( "enumType", ti.m_enumField.name() )

    def testPtr(self):
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
142
        self.assertEqual( "UInt8B*", target.module.type( "pbigValue" ).name() )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
143 144
        self.assertEqual( "structTest*", target.module.type( "structTest*" ).name() )
        self.assertEqual( "UInt2B*", pykd.typeInfo( "UInt2B*" ).name() )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
145 146 147 148
        self.assertEqual( "Void*",  target.module.type( "voidPtr" ).name() )
        self.assertEqual( "Void*[3]", target.module.type( "voidPtrArray" ).name())
        #self.assertEqual( "<function>*", target.module.type( "g_ptrToFunction" ).name())
        #self.assertEqual( "<function>*[4]", target.module.type( "g_arrOfPtrToFunc" ).name())
149 150 151 152

    def testUnion(self):
        ti = target.module.type("unionTest")
        self.assertEqual( 0, ti.fieldOffset("m_doubleValue") )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
153 154 155
        self.assertEqual( 0, ti.fieldOffset("m_value") )
        self.assertEqual( 0, ti.fieldOffset("m_structValue") )
        self.assertEqual( ti.size(), ti.m_structValue.size() )
156 157

    def testDeref(self):
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
158 159
        ti = pykd.typeInfo("Int1B*")
        self.assertEqual( "Int1B", ti.deref().name() )
160

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
161 162 163 164
        ti = target.module.type("structTest*")
        self.assertEqual( "structTest", ti.deref().name() )

        ti =  pykd.typeInfo("structTest[2]")
165
        self.assertEqual( "structTest", ti.deref().name() )
166 167

        ti = target.module.type("classChild")
168
        self.assertRaises( pykd.TypeException, ti.deref )
169 170

    def testNestedStruct( self ):
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
171
        ti = target.module.type("structWithNested")
ussrhero's avatar
ussrhero committed
172 173 174 175 176 177
        self.assertTrue( ti.hasField("m_field"))
        self.assertTrue( ti.hasField("m_field3"))
        self.assertTrue( ti.hasField("m_unnameStruct"))
        self.assertTrue( ti.m_unnameStruct.hasField("m_field2"))
        self.assertFalse( ti.hasField( "m_field2" ) )
        self.assertFalse( ti.hasField( "m_nestedFiled" ) )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
178
        ti = target.module.type("structWithNested::Nested")
ussrhero's avatar
ussrhero committed
179
        self.assertTrue( ti.hasField( "m_nestedFiled" ) )
180 181

    def testPrint(self):
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
182 183 184 185
        self.assertTrue( str(target.module.type( "ucharVar" ) ) )
        self.assertTrue( str(target.module.type( "ushortVar" ) ) )
        self.assertTrue( str(target.module.type( "ulongVar" ) ) )
        self.assertTrue( str(target.module.type( "ulonglongVar" ) ) )
186 187 188 189 190 191 192 193 194 195
        self.assertTrue( str(target.module.type( "g_structWithBits" ) ) )
        self.assertTrue( str(target.module.type( "g_structTest" ) ) )
        self.assertTrue( str(target.module.type( "g_structTest1" ) ) )
        self.assertTrue( str(target.module.type( "g_testArray" ) ) )
        self.assertTrue( str(target.module.type( "g_structTestPtr" ) ) )
        self.assertTrue( str(target.module.type( "g_structTestPtrPtr" ) ) )
        self.assertTrue( str(target.module.type( "longlongArray" ) ) )
        self.assertTrue( str(target.module.type( "intMatrix4" ) ) )
        self.assertTrue( str(target.module.type( "ptrIntMatrix" ) ) )
        self.assertTrue( str(target.module.type( "g_classChild" ) ) )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
196 197 198 199
#        self.assertTrue( str(target.module.type( "g_listHead" ) ) )
#        self.assertTrue( str(target.module.type( "g_voidPtr" ) ) )
#        self.assertTrue( str(target.module.type( "g_arrOfPtrToFunc" ) ) )
#        self.assertTrue( str(target.module.type( "g_unTypedPtrToFunction" ) ) )
200

201 202 203 204 205 206 207 208 209 210 211 212 213 214
    def testTypedef(self):
        self.assertEqual( "structTest", pykd.typeInfo( "g_structTypeDef" ).name() )
        self.assertEqual( "structTest", pykd.typeInfo( "structTestTypeDef" ).name() )

    def testStaticField(self):
        ti = pykd.typeInfo( "g_classChild" )
        self.assertNotEqual( 0, ti.staticOffset( "m_staticField" ) )
        self.assertNotEqual( 0, ti.staticOffset("m_stdstr") )
        if not ti.staticOffset("m_staticConst"):
            self.assertFalse( "MS DIA bug: https://connect.microsoft.com/VisualStudio/feedback/details/737430" )

    def testVfnTable(self):
        ti = pykd.typeInfo( "g_classChild" )
        self.assertTrue( hasattr( ti, "__VFN_table" ) )
215

216 217
    def testUdtSubscribe(self):
        ti = pykd.typeInfo( "g_virtChild" )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
218
        self.assertEqual( 6, len(ti) )
219 220
        for field in ti:
             str( field )
221

222 223 224
    def testEnumSubscribe(self):
        ti = pykd.typeInfo( "enumType" )
        self.assertEqual( 3, len(ti) )
225
        self.assertEqual( [ 1, 2, 3], [ int(field) for field in ti ] )
226 227
        self.assertEqual( [ ( "ONE", 1), ("TWO", 2), ("THREE", 3) ], ti.fields() )

228 229 230
    def testStructNullSize(self):
        ti = target.module.type("structNullSize")
        self.assertEqual( 0, len(ti) )
231

232
    def testDerefName(self):
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
233 234
        entry = pykd.typedVar("g_listHead").flink
        self.assertEqual( "listEntry*", entry.type().name() )
235 236

    def testPtrTo(self):
237 238 239
        ti = pykd.typeInfo("UInt8B").ptrTo()
        self.assertTrue( "UInt8B*", ti.name() )
        self.assertNotEqual( 0, ti.size() )
240

241 242
    def testArrayOf(self):
        ti = pykd.typeInfo("UInt8B").arrayOf(10)
243
        self.assertTrue( "UInt8B[10]", ti.name() )
244 245
        
    def testCompareWihNone(self):
246
        ti = pykd.typeInfo("UInt8B")
247
        if ti == None:
248 249 250 251 252 253 254
            pass
        if ti != None:
            pass
        if not ti:
            pass
        if ti:
            pass
255 256 257 258 259

    def testFunction(self):
        functype = target.module.typedVar( "CdeclFuncPtr" ).type().deref()
        self.assertTrue( functype.isFunction() )

260 261 262
        functype = target.module.typedVar( "g_variadicFuncPtr" ).type().deref()
        self.assertTrue( functype.isFunction() )

263 264 265 266
    def testFunctionArgs(self):
        functype = target.module.typedVar( "CdeclFuncPtr" ).type().deref()
        self.assertEqual( [ arg.name() for arg in functype ], ["Int4B", "Float"] )

267
        functype = target.module.typedVar( "g_variadicFuncPtr" ).type().deref()
268
        self.assertEqual( [ arg.name() for arg in functype ], ["Int4B", "NoType"] )
269

270 271 272 273 274 275 276 277 278 279 280
    def testFunctionCallConv(self):
        functype = target.module.typedVar( "CdeclFuncPtr" ).type().deref()
        self.assertEqual( functype.getCallingConvention(), pykd.callingConvention.NearC )

    def testFunctionThis(self):
        functype = target.module.typedVar( "MethodPtr" ).type().deref()
        self.assertEqual( [ arg.name() for arg in functype ], ["FuncTestClass*"] )

        functype = target.module.typedVar( "CdeclStaticMethodPtr" ).type().deref()
        self.assertEqual( [ arg.name() for arg in functype ], [] )

281 282 283 284
    def testFunctionName(self):
        functype = target.module.typedVar( "CdeclFuncPtr" ).type().deref()
        self.assertEqual(functype.name(), "Void(__cdecl)(Int4B, Float)")

285 286 287
        functype = target.module.typedVar( "MethodPtr" ).type().deref()
        self.assertEqual(functype.name(), "Void(__thiscall FuncTestClass::)()")

288 289 290 291 292 293
        functype = target.module.typedVar( "ArrayOfCdeclFuncPtr" ).type()[0].deref()
        self.assertEqual(functype.name(), "Void(__cdecl)(Int4B, Float)")

        functype = target.module.typedVar( "ArrayOfMethodPtr" ).type()[0].deref()
        self.assertEqual(functype.name(), "Void(__thiscall FuncTestClass::)()")

294 295 296
        functype = target.module.typedVar( "g_variadicFuncPtr" ).type().deref()
        self.assertEqual(functype.name(), "Void(__cdecl)(Int4B, ...)")

297 298 299
    def testFunctionPtrName(self):
        funcptrtype = target.module.typedVar( "CdeclFuncPtr" ).type()
        self.assertEqual(funcptrtype.name(), "Void(__cdecl*)(Int4B, Float)")
300

301
        functype = target.module.typedVar( "MethodPtr" ).type()
302
        self.assertEqual(functype.name(), "Void(__thiscall FuncTestClass::*)()")
303

304 305 306
        funcptrtype = target.module.typedVar( "g_variadicFuncPtr" ).type()
        self.assertEqual(funcptrtype.name(), "Void(__cdecl*)(Int4B, ...)")

307 308 309 310
    def testFunctionArrName(self):
        funcptrtype = target.module.typedVar( "ArrayOfCdeclFuncPtr" ).type()
        self.assertEqual(funcptrtype.name(), "Void(__cdecl*[3])(Int4B, Float)")

311
        functype = target.module.typedVar( "ArrayOfMethodPtr" ).type()
312
        self.assertEqual(functype.name(), "Void(__thiscall FuncTestClass::*[2])()")
313 314 315 316 317 318

    def testDir(self):
        ti = target.module.type("structTest")
        self.assertEqual(5, len(dir(ti)))
        self.assertTrue("m_field3" in dir(ti))
        self.assertFalse("m_field33" in dir(ti))
319 320 321 322 323 324 325 326 327

    def testEnumTypes(self):
        lst = target.module.enumTypes()
        self.assertNotEqual([], lst)
        lst = target.module.enumTypes("structTest")
        self.assertEqual(["structTest"], lst)
        lst = target.module.enumTypes("NonExsistType")
        self.assertEqual([],lst)

328 329
    def testArrayOverflow(self):
        self.assertRaises(pykd.TypeException, pykd.baseTypes.UInt8B.arrayOf, 0xFFFFFFFFFFFFFFFF)
330 331

    def testMethodCount(self):
332 333
        self.assertEqual( 14, target.module.type("classChild").getNumberMethods() )
        
334 335
    def testGetMethod(self):
        self.assertEqual( "Int4B(__thiscall classChild::)(Int4B)", target.module.type("classChild").method("childMethod").name() )
336
        self.assertEqual( "Int4B(__thiscall classChild::)(Int4B)", target.module.type("classChild").childMethod.name() )
337
        self.assertEqual( "Int4B(__thiscall classChild::)(Int4B)", target.module.type("classChild").method(1).name() )
338

339 340 341 342
    def testMethods(self):
        self.assertEqual( 14, len(target.module.type("classChild").methods()))

    def testGetBaseClass(self):
343
        classChild = target.module.type("classChild")
344
        self.assertEqual( ["classBase1", "classBase2"], [ classChild.baseClass(i).name() for i in range(classChild.getNumberBaseClasses()) ] )
345 346 347 348 349 350 351
        self.assertEqual( ["classBase1", "classBase2"], [ name for name, _, _ in classChild.baseClasses()] )

    def testGetBaseClassOffset(self):
        classChild = target.module.type("classChild")
        self.assertEqual( classChild.baseClassOffset(0), classChild.baseClassOffset('classBase1'))
        self.assertEqual(classChild.baseClassOffset(1), classChild.baseClassOffset('classBase2'))

ussrhero's avatar
ussrhero committed
352 353 354 355 356
    def  testPdbTypeProvider(self):
        pdb = target.module.symfile()
        typeProvider = pykd.getTypeInfoProviderFromPdb(pdb)
        self.assertEqual("structTest", typeProvider.getTypeByName("structTest").name())
        self.assertEqual("structTest", typeProvider.structTest.name())
ussrhero's avatar
ussrhero committed
357
        self.assertEqual(16, len(list(typeProvider.typeIterator("*struct*"))))
ussrhero's avatar
ussrhero committed
358 359 360 361

    def testScopeName(self):
        self.assertEqual( target.module.name(), pykd.typeInfo( "structTest" ).scopeName() )
        self.assertEqual( target.module.name(), pykd.typeInfo( "structWithNested::Nested" ).scopeName() )
362 363 364 365 366 367
 
    def testContain(self):
        ti = target.module.type( "structTest" )
        self.assertTrue("m_field1" in ti)
        self.assertFalse("NotExist" in ti)
        self.assertRaises(Exception, lambda t : 2 in t, ti)
ussrhero's avatar
ussrhero committed
368 369 370 371 372 373

    def testTemplateType(self):
        ti = target.module.type("g_testTemplateTwoTypes")
        self.assertTrue(ti.isTemplate)
        self.assertEqual(['int', 'TestClassTemplate<int>'], ti.getTemplateArgs() )