diff --git a/test/scripts/_run_pykdtest.cmd b/test/scripts/_run_pykdtest.cmd new file mode 100644 index 0000000..c8b0c14 --- /dev/null +++ b/test/scripts/_run_pykdtest.cmd @@ -0,0 +1,23 @@ +::@echo on + +:: Pass $(TargetDir)\ from Visual Studio +set TestAppPath=%1 + +:: Pass $(PlatformName) from Visual Studio +set TestAppPlatform=%2 + +set Arch=x64 +if "%PROCESSOR_ARCHITECTURE%" == "x86" ( + if not defined PROCESSOR_ARCHITEW6432 set Arch=x86 +) + +set PythonRegKey=HKLM\Software\Python\PythonCore\2.6\InstallPath + +set RegSwitch=64 +if "%TestAppPlatform%"=="Win32" set RegSwitch=32 + +for /F "tokens=3*" %%A in ('reg.exe query %PythonRegKey% /ve /reg:%RegSwitch% 2^>NUL ^| FIND "REG_SZ"') do set PythonInstallPath=%%A + +%PythonInstallPath%python.exe "%~dp0pykdtest.py" %TestAppPath% + +::pause \ No newline at end of file diff --git a/test/scripts/basetest.py b/test/scripts/basetest.py new file mode 100644 index 0000000..fd2f3db --- /dev/null +++ b/test/scripts/basetest.py @@ -0,0 +1,139 @@ +# +# +# + +import unittest +import target +import pykd + +class BaseTest( unittest.TestCase ): + + def testOldSupportedRoutines( self ): + """ Branch test: old API 0.0.x what must be available """ + + self.assertTrue( hasattr(pykd, 'addSynSymbol') ) + self.assertTrue( hasattr(pykd, 'attachKernel') ) + self.assertTrue( hasattr(pykd, 'attachProcess') ) + self.assertTrue( hasattr(pykd, 'addr64') ) + self.assertTrue( hasattr(pykd, 'breakin') ) + self.assertTrue( hasattr(pykd, 'compareMemory') ) + self.assertTrue( hasattr(pykd, 'containingRecord') ) + self.assertTrue( hasattr(pykd, 'dbgCommand') ) + self.assertTrue( hasattr(pykd, 'dprint') ) + self.assertTrue( hasattr(pykd, 'dprintln') ) + self.assertTrue( hasattr(pykd, 'debuggerPath') ) + self.assertTrue( hasattr(pykd, 'delAllSynSymbols') ) + self.assertTrue( hasattr(pykd, 'delSynSymbol') ) + self.assertTrue( hasattr(pykd, 'delSynSymbolsMask') ) + self.assertTrue( hasattr(pykd, 'expr') ) + self.assertTrue( hasattr(pykd, 'findSymbol') ) + self.assertTrue( hasattr(pykd, 'getCurrentProcess') ) + self.assertTrue( hasattr(pykd, 'getCurrentStack') ) + self.assertTrue( hasattr(pykd, 'getImplicitThread') ) + self.assertTrue( hasattr(pykd, 'getOffset') ) + self.assertTrue( hasattr(pykd, 'getPdbFile') ) + self.assertTrue( hasattr(pykd, 'getProcessorMode') ) + self.assertTrue( hasattr(pykd, 'getProcessorType') ) + self.assertTrue( hasattr(pykd, 'getThreadList') ) + self.assertTrue( hasattr(pykd, 'go') ) + self.assertTrue( hasattr(pykd, 'is64bitSystem') ) + self.assertTrue( hasattr(pykd, 'isDumpAnalyzing') ) + self.assertTrue( hasattr(pykd, 'isKernelDebugging') ) + self.assertTrue( hasattr(pykd, 'isValid') ) + self.assertTrue( hasattr(pykd, 'isWindbgExt') ) + self.assertTrue( hasattr(pykd, 'loadAnsiString') ) + self.assertTrue( hasattr(pykd, 'loadBytes') ) + self.assertTrue( hasattr(pykd, 'loadCStr') ) + self.assertTrue( hasattr(pykd, 'loadChars') ) + self.assertTrue( hasattr(pykd, 'loadDWords') ) + self.assertTrue( hasattr(pykd, 'loadDump') ) + self.assertTrue( hasattr(pykd, 'loadModule') ) + self.assertTrue( hasattr(pykd, 'loadQWords') ) + self.assertTrue( hasattr(pykd, 'loadPtrs') ) + self.assertTrue( hasattr(pykd, 'loadSignBytes') ) + self.assertTrue( hasattr(pykd, 'loadSignDWords') ) + self.assertTrue( hasattr(pykd, 'loadSignQWords') ) + self.assertTrue( hasattr(pykd, 'loadSignWords') ) + self.assertTrue( hasattr(pykd, 'loadUnicodeString') ) + self.assertTrue( hasattr(pykd, 'loadWChars') ) + self.assertTrue( hasattr(pykd, 'loadWStr') ) + self.assertTrue( hasattr(pykd, 'loadWords') ) + self.assertTrue( hasattr(pykd, 'ptrByte') ) + self.assertTrue( hasattr(pykd, 'ptrDWord') ) + self.assertTrue( hasattr(pykd, 'ptrMWord') ) + self.assertTrue( hasattr(pykd, 'ptrPtr') ) + self.assertTrue( hasattr(pykd, 'ptrQWord') ) + self.assertTrue( hasattr(pykd, 'ptrSignByte') ) + self.assertTrue( hasattr(pykd, 'ptrSignDWord') ) + self.assertTrue( hasattr(pykd, 'ptrSignMWord') ) + self.assertTrue( hasattr(pykd, 'ptrSignQWord') ) + self.assertTrue( hasattr(pykd, 'ptrSignWord') ) + self.assertTrue( hasattr(pykd, 'ptrSize') ) + self.assertTrue( hasattr(pykd, 'ptrWord') ) + self.assertTrue( hasattr(pykd, 'rdmsr') ) + self.assertTrue( hasattr(pykd, 'reg') ) + self.assertTrue( hasattr(pykd, 'setCurrentProcess') ) + self.assertTrue( hasattr(pykd, 'setImplicitThread') ) + self.assertTrue( hasattr(pykd, 'setProcessorMode') ) + self.assertTrue( hasattr(pykd, 'sizeof') ) + self.assertTrue( hasattr(pykd, 'startProcess') ) + self.assertTrue( hasattr(pykd, 'step') ) + self.assertTrue( hasattr(pykd, 'symbolsPath') ) + self.assertTrue( hasattr(pykd, 'typedVarArray') ) + self.assertTrue( hasattr(pykd, 'typedVarList') ) + self.assertTrue( hasattr(pykd, 'trace') ) + self.assertTrue( hasattr(pykd, 'wrmsr') ) + + + def testOldSupportedClass( self ): + """ Branch test: old API 0.0.x class must be available """ + self.assertTrue( hasattr(pykd, 'BaseException') ) + self.assertTrue( hasattr(pykd, 'MemoryException') ) + self.assertTrue( hasattr(pykd, 'TypeException') ) + self.assertTrue( hasattr(pykd, 'WaitEventException') ) + self.assertTrue( hasattr(pykd, 'cpuReg') ) + self.assertTrue( hasattr(pykd, 'disasm') ) + self.assertTrue( hasattr(pykd, 'ext') ) + self.assertTrue( hasattr(pykd, 'intBase') ) + self.assertTrue( hasattr(pykd, 'typeInfo') ) + self.assertTrue( hasattr(pykd, 'typedVar') ) + + def testOldRemovedApi( self ): + """ Branch test: old API 0.0.x what should be removed """ + self.assertFalse( hasattr(pykd, 'dbgModuleClass') ) + self.assertFalse( hasattr(pykd, 'dbgStackFrameClass') ) + self.assertFalse( hasattr(pykd, 'debugEvent') ) + self.assertFalse( hasattr(pykd, 'findModule') ) + self.assertFalse( hasattr(pykd, 'loadLinkedList') ) + self.assertFalse( hasattr(pykd, 'reloadModule') ) + self.assertFalse( hasattr(pykd, 'windbgIn') ) + self.assertFalse( hasattr(pykd, 'windbgOut') ) + self.assertFalse( hasattr(pykd, 'bp') ) + + def testNewAddededApi( self ): + """ Branch test: new API 0.1.x what must be available """ + # self.assertTrue( hasattr(pykd, 'createDbgClient') ) + self.assertTrue( hasattr(pykd, 'detachProcess') ) + self.assertTrue( hasattr(pykd, 'diaLoadPdb') ) + self.assertTrue( hasattr(pykd, 'getDebuggeeType' ) ) + self.assertTrue( hasattr(pykd, 'getLocals' ) ) + self.assertTrue( hasattr(pykd, 'getExecutionStatus' ) ) + self.assertTrue( hasattr(pykd, 'killProcess') ) + self.assertTrue( hasattr(pykd, 'loadExt') ) + self.assertTrue( hasattr(pykd, 'loadPtrList') ) + self.assertTrue( hasattr(pykd, 'setExecutionStatus') ) + self.assertTrue( hasattr(pykd, 'waitForEvent') ) + + self.assertTrue( hasattr(pykd, 'setBp') ) + self.assertTrue( hasattr(pykd, 'getAllBp') ) + self.assertTrue( hasattr(pykd, 'removeBp') ) + + self.assertTrue( hasattr(pykd, 'DiaException') ) + self.assertTrue( hasattr(pykd, 'DiaScope') ) + self.assertTrue( hasattr(pykd, 'DiaSymbol') ) + # self.assertTrue( hasattr(pykd, 'dbgClient') ) + self.assertTrue( hasattr(pykd, 'din') ) + self.assertTrue( hasattr(pykd, 'dout') ) + self.assertTrue( hasattr(pykd, 'eventHandler' ) ) + self.assertTrue( hasattr(pykd, 'module') ) + self.assertTrue( hasattr(pykd, 'stackFrame') ) diff --git a/test/scripts/clienttest.py b/test/scripts/clienttest.py new file mode 100644 index 0000000..fdcf4ac --- /dev/null +++ b/test/scripts/clienttest.py @@ -0,0 +1,44 @@ + +import unittest +import target +import pykd + +class DbgClientTest( unittest.TestCase ): + + def testGetDebuggeeType( self ): + c, q = pykd.getDebuggeeType() + self.assertEqual( c, pykd.DEBUG_CLASS_USER_WINDOWS ) + self.assertEqual( q, pykd.DEBUG_USER_WINDOWS_PROCESS ) + + def testIsKernelDebugging( self ): + self.assertFalse( pykd.isKernelDebugging() ) + + def testNumberProcessors( self ): + """Number of processors can not be 0""" + self.assertNotEqual( 0, pykd.getNumberProcessors() ) + + def testPageSize( self ): + """Size of memory page must be >= 4kb""" + self.assertTrue( pykd.getPageSize() >= 4*1024 ) + + def testIsDumpAnalyzing( self ): + self.assertFalse( pykd.isDumpAnalyzing() ) + + def testExecutionStatus( self ): + self.assertEqual( pykd.DEBUG_STATUS_BREAK, pykd.getExecutionStatus() ) + pykd.setExecutionStatus( pykd.DEBUG_STATUS_GO ) + pykd.waitForEvent() + self.assertEqual( pykd.DEBUG_STATUS_BREAK, pykd.getExecutionStatus() ) + + def testPdbFile( self ): + self.assertNotEqual( '', pykd.getPdbFile( target.module.begin() ) ) + + def testProcessorMode( self ): + self.assertNotEqual( '', pykd.getProcessorMode() ) + self.assertNotEqual( '', pykd.getProcessorType() ) + + def testThreadList( self ): + self.assertNotEqual( 0, len(pykd.getThreadList()) ) + + def testSymbolsPath( self ): + self.assertNotEqual( '', pykd.symbolsPath() ) diff --git a/test/scripts/customtypestest.py b/test/scripts/customtypestest.py new file mode 100644 index 0000000..bd702ed --- /dev/null +++ b/test/scripts/customtypestest.py @@ -0,0 +1,133 @@ +"""Custom types tests""" + +import unittest +import target +import pykd + +class CustomTypesTest(unittest.TestCase): + def testCommonStruct(self): + + tb = pykd.typeBuilder() + + mySubStruct =tb.createStruct("MySubCustomStruct") + mySubStruct.append( "m_uint1", tb.UInt1B ) + mySubStruct.append( "m_uint2", tb.UInt2B ) + + mySubUnion = tb.createUnion("MySubCustomUnion") + mySubUnion.append( "m_uint1", tb.UInt1B ) + mySubUnion.append( "m_uint2", tb.UInt2B ) + + myType = tb.createStruct("MyCustomStruct") + myType.append( "m_uint1", tb.UInt1B ) + myType.append( "m_uint4", tb.UInt4B ) + myType.append( "m_uint2", tb.UInt2B ) + myType.append( "m_struct", mySubStruct ) + myType.append( "m_union", mySubUnion ) + myType.append( "m_uint8", tb.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): + + tb = pykd.typeBuilder() + + myType = tb.createUnion("MyCustomStruct") + myType.append( "m_uint1", tb.UInt1B ) + myType.append( "m_uint4", tb.UInt4B ) + myType.append( "m_uint2", tb.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 testEmptyType(self): + tb = pykd.typeBuilder() + + myEmptyStruct1 = tb.createStruct("EmptyStruct1") + self.assertEqual( 0, myEmptyStruct1.size() ) + + myEmptyStruct1.append("m_emptyStruct2", tb.createStruct("EmptyStruct2")) + self.assertEqual( 0, myEmptyStruct1.size() ) + + myEmptyUnion1 = tb.createUnion("EmptyUnion1") + self.assertEqual( 0, myEmptyUnion1.size() ) + + myEmptyStruct1.append("m_emptyUnion2", myEmptyUnion1) + self.assertEqual( 0, myEmptyStruct1.size() ) + + myEmptyUnion1.append("m_emptyStruct3", tb.createStruct("EmptyStruct3")) + self.assertEqual( 0, myEmptyUnion1.size() ) + + def testDupFieldName(self): + + tb = pykd.typeBuilder() + + myType = tb.createStruct("MyCustomStruct") + exceptionRised = False + myType.append( "m_uint1", tb.UInt1B ) + try: + myType.append( "m_uint1", tb.UInt1B ) + except pykd.TypeException: + exceptionRised = True + self.assertTrue(exceptionRised) + + myType = tb.createUnion("MyCustomStruct") + exceptionRised = False + myType.append( "m_uint1", tb.UInt1B ) + try: + myType.append( "m_uint1", tb.UInt1B ) + except pykd.TypeException: + exceptionRised = True + self.assertTrue(exceptionRised) + + def testBasicType(self): + tb = pykd.typeBuilder() + self.assertEqual( 1, tb.UInt1B.size() ) + self.assertEqual( 2, tb.UInt2B.size() ) + self.assertEqual( 4, tb.UInt4B.size() ) + self.assertEqual( 8, tb.UInt8B.size() ) + self.assertEqual( 1, tb.Int1B.size() ) + self.assertEqual( 2, tb.Int2B.size() ) + self.assertEqual( 4, tb.Int4B.size() ) + self.assertEqual( 8, tb.Int8B.size() ) + self.assertEqual( 1, tb.Bool.size() ) + self.assertEqual( 1, tb.Char.size() ) + self.assertEqual( 2, tb.WChar.size() ) + self.assertEqual( 4, tb.Long.size() ) + self.assertEqual( 4, tb.ULong.size() ) + + def testVoidPtr(self): + self.assertEqual( 4, pykd.typeBuilder(4).VoidPtr.size() ) + self.assertEqual( 8, pykd.typeBuilder(8).VoidPtr.size() ) + self.assertEqual( pykd.ptrSize(), pykd.typeBuilder().VoidPtr.size() ) + self.assertEqual( 4, pykd.typeBuilder(4).UInt1B.ptrTo().size() ) + self.assertEqual( 8, pykd.typeBuilder(8).UInt1B.ptrTo().size() ) + self.assertEqual( pykd.ptrSize(), pykd.typeBuilder().UInt1B.ptrTo().size() ) + + def testPtrToCustomType(self): + tb = pykd.typeBuilder() + mySubStruct =tb.createStruct("MySubCustomStruct") + mySubStruct.append( "m_uint1", tb.UInt1B ) + mySubStruct.append( "m_uint2", tb.UInt2B ) + mySubStructPtr = mySubStruct.ptrTo() + self.assertEqual( pykd.ptrSize(), mySubStructPtr.size() ) + + diff --git a/test/scripts/dbgcmd.py b/test/scripts/dbgcmd.py new file mode 100644 index 0000000..a425db4 --- /dev/null +++ b/test/scripts/dbgcmd.py @@ -0,0 +1,17 @@ + +import unittest +import target +import pykd + +class DbgcmdTest( unittest.TestCase ): + + def testDbgCommand( self ): + self.assertNotEqual( "", pykd.dbgCommand("lm") ) + +# def testDbgExt( self ): +# #ext = pykd.loadExt( "ext" ) +# #self.assertNotEqual( "", ext.call("help", "") ) + + def testExpr( self ): + self.assertEqual( 8, pykd.expr( "poi(targetapp!g_ulonglongValue)" ) ) + diff --git a/test/scripts/diatest.py b/test/scripts/diatest.py new file mode 100644 index 0000000..77a3e4d --- /dev/null +++ b/test/scripts/diatest.py @@ -0,0 +1,179 @@ +""" +Tests for pyDia +""" + +import unittest +import target +import pykd + +from sets import Set + +class DiaTest( unittest.TestCase ): + + def testCtor(self): + """ DiaSymbol can not be created direct """ + try: pykd.DiaSymbol() + except RuntimeError: pass + + def testFind(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + self.assertNotEqual(0, len(gScope)) + symFunction = gScope.find("FuncWithName0") + self.assertTrue(1 == len( symFunction )) + symFunction = gScope.findEx(pykd.SymTagNull, + "FuNc*Name?", + pykd.nsCaseInRegularExpression) + self.assertTrue(len(symFunction) > 1) + + def testSize(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + self.assertEqual(1, gScope["g_ucharValue"].type().size()) + self.assertEqual(2, gScope["g_ushortValue"].type().size()) + self.assertEqual(4, gScope["g_ulongValue"].type().size()) + self.assertEqual(8, gScope["g_ulonglongValue"].type().size()) + + def testValue(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + self.assertEqual(0x5555, gScope["g_constNumValue"].value()) + self.assertEqual(True, gScope["g_constBoolValue"].value()) + + def testName(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + self.assertEqual( "g_constNumValue", + gScope["g_constNumValue"].name() ) + self.assertEqual( "FuncWithName0", + gScope["FuncWithName0"].name() ) + + def testRva(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + _rva = gScope["FuncWithName0"].rva() + self.assertNotEqual(0, _rva) + modLen = target.module.end() - target.module.begin() + self.assertTrue( _rva < modLen ) + _rva = gScope["g_string"].rva() + self.assertNotEqual(0, _rva) + self.assertTrue( _rva < modLen ) + + def testSymTag(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + self.assertEqual( pykd.SymTagFunction, + gScope["FuncWithName0"].symTag() ) + self.assertEqual( pykd.SymTagData, + gScope["g_string"].symTag() ) + + def testLocType(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + self.assertEqual( pykd.LocIsConstant, + gScope["g_constNumValue"].locType() ) + self.assertEqual( pykd.LocIsStatic, + gScope["FuncWithName1"].locType() ) + + def testBasicType(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + self.assertFalse(gScope["g_string"].type().isBasic()) + self.assertEqual( pykd.btBool, + gScope["g_constBoolValue"].type().baseType() ) + self.assertEqual( pykd.btULong, + gScope["g_ulongValue"].type().baseType() ) + + def testBasicName(self): + self.assertEqual( "NoType", pykd.diaBasicType[ pykd.btNoType ] ) + self.assertEqual( "Void", pykd.diaBasicType[ pykd.btVoid ] ) + self.assertEqual( "Char", pykd.diaBasicType[ pykd.btChar ] ) + self.assertEqual( "WChar", pykd.diaBasicType[ pykd.btWChar ] ) + self.assertEqual( "Int", pykd.diaBasicType[ pykd.btInt ] ) + self.assertEqual( "UInt", pykd.diaBasicType[ pykd.btUInt ] ) + self.assertEqual( "Float", pykd.diaBasicType[ pykd.btFloat ] ) + self.assertEqual( "BCD", pykd.diaBasicType[ pykd.btBCD ] ) + self.assertEqual( "Bool", pykd.diaBasicType[ pykd.btBool ] ) + self.assertEqual( "Long", pykd.diaBasicType[ pykd.btLong ] ) + self.assertEqual( "ULong", pykd.diaBasicType[ pykd.btULong ] ) + self.assertEqual( "Currency", pykd.diaBasicType[ pykd.btCurrency ] ) + self.assertEqual( "Date", pykd.diaBasicType[ pykd.btDate ] ) + self.assertEqual( "Variant", pykd.diaBasicType[ pykd.btVariant ] ) + self.assertEqual( "Complex", pykd.diaBasicType[ pykd.btComplex ] ) + self.assertEqual( "Bit", pykd.diaBasicType[ pykd.btBit ] ) + self.assertEqual( "BSTR", pykd.diaBasicType[ pykd.btBSTR ] ) + self.assertEqual( "Hresult", pykd.diaBasicType[ pykd.btHresult ] ) + + def testBits(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + structWithBits = gScope["structWithBits"] + bitField = structWithBits["m_bit0_4"] + self.assertEqual(pykd.LocIsBitField, bitField.locType()) + self.assertEqual(0, bitField.bitPos()) + self.assertEqual(5, bitField.size()) + bitField = structWithBits["m_bit5"] + self.assertEqual(pykd.LocIsBitField, bitField.locType()) + self.assertEqual(5, bitField.bitPos()) + self.assertEqual(1, bitField.size()) + bitField = structWithBits["m_bit6_7"] + self.assertEqual(pykd.LocIsBitField, bitField.locType()) + self.assertEqual(6, bitField.bitPos()) + self.assertEqual(2, bitField.size()) + + def testIndexId(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + self.assertNotEqual( gScope["classChild"].indexId(), + gScope["classBase"].indexId() ) + self.assertNotEqual( gScope["FuncWithName0"].indexId(), + gScope["FuncWithName1"].indexId() ) + + def testUdtKind(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + self.assertEqual(pykd.UdtStruct, gScope["structTest"].udtKind()) + self.assertEqual(pykd.UdtUnion, gScope["unionTest"].udtKind()) + self.assertEqual(pykd.UdtClass, gScope["classBase"].udtKind()) + + def testOffset(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + structTest = gScope["structTest"] + self.assertEqual( 0, structTest["m_field0"].offset() ) + self.assertTrue( structTest["m_field0"].offset() < + structTest["m_field1"].offset() ) + self.assertTrue( structTest["m_field1"].offset() < + structTest["m_field2"].offset() ) + self.assertTrue( structTest["m_field2"].offset() < + structTest["m_field3"].offset() ) + self.assertTrue( structTest["m_field3"].offset() < + structTest.size() ) + + def testMachine(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + machine = gScope.machineType() + self.assertTrue( (machine == pykd.IMAGE_FILE_MACHINE_I386) or + (machine == pykd.IMAGE_FILE_MACHINE_AMD64) ) + + def testFindByRva(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + func = gScope["FuncWithName0"] + tplSymOffset = gScope.findByRva(func.rva(), pykd.SymTagFunction) + self.assertEqual(tplSymOffset[0].indexId(), func.indexId()) + self.assertEqual(tplSymOffset[1], 0) + tplSymOffset = gScope.findByRva(func.rva()+2, pykd.SymTagFunction) + self.assertEqual(tplSymOffset[0].indexId(), func.indexId()) + self.assertEqual(tplSymOffset[1], 2) + + def testSymbolById(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + func = gScope["FuncWithName0"] + self.assertEqual( gScope.symbolById(func.indexId()).indexId(), + func.indexId()) + + def testCount(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + var = gScope["FuncWithName1"]["_unionTest"] + self.assertEqual( 2, var.type().count() ) + + def testDataKind(self): + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + self.assertEqual( pykd.DataIsGlobal, gScope["g_structTest"].dataKind() ) + self.assertEqual( pykd.DataIsParam, gScope["EnumWindowsProc1"]["hWindow"].dataKind() ) + + def testSymbolHash(self): + """Test set of DIA symbols""" + gScope = pykd.diaLoadPdb( str(target.module.pdb()) ) + symSet = set([ gScope["g_structTest"], gScope["EnumWindowsProc1"], gScope["g_structTest"] ]) + self.assertEqual( 2, len(symSet) ) + self.assertTrue( gScope["g_structTest"] in symSet ) + self.assertFalse( gScope["EnumWindowsProc2"] in symSet ) diff --git a/test/scripts/ehexcepttest.py b/test/scripts/ehexcepttest.py new file mode 100644 index 0000000..4ca4485 --- /dev/null +++ b/test/scripts/ehexcepttest.py @@ -0,0 +1,46 @@ +"""Exception event test""" + +import unittest +import target +import pykd +import testutils + +class ExceptionHandler(pykd.eventHandler): + def __init__(self): + pykd.eventHandler.__init__(self) + self.accessViolationOccured = False + + def onException(self, exceptInfo): + """Exception handler""" + + self.accessViolationOccured = exceptInfo.ExceptionCode == 0xC0000005 + + if self.accessViolationOccured: + self.param0 = exceptInfo.Parameters[0] + self.param1 = exceptInfo.Parameters[1] + return pykd.eventResult.Break + + return pykd.eventResult.NoChange + +class EhExceptionTest(unittest.TestCase): + """Exception event test""" + + def testException(self): + """Start new process and track exceptions""" + _locProcessId = pykd.startProcess( target.appPath + " -testExceptions" ) + with testutils.ContextCallIt( testutils.KillProcess(_locProcessId) ) as killStartedProcess : + exceptionHandler = ExceptionHandler() + + while not exceptionHandler.accessViolationOccured: + pykd.go() + + self.assertEqual( pykd.lastEvent(), pykd.eventType.Exception ) + + self.assertTrue( exceptionHandler.accessViolationOccured ) + self.assertEqual( exceptionHandler.param0, 1 ) # write + self.assertEqual( exceptionHandler.param1, 2 ) # addr + + exceptInfo = pykd.lastException() + self.assertEqual( exceptInfo.ExceptionCode, 0xC0000005 ) + self.assertEqual( exceptionHandler.param0, exceptInfo.Parameters[0] ) + self.assertEqual( exceptionHandler.param1, exceptInfo.Parameters[1] ) diff --git a/test/scripts/ehloadtest.py b/test/scripts/ehloadtest.py new file mode 100644 index 0000000..437cc86 --- /dev/null +++ b/test/scripts/ehloadtest.py @@ -0,0 +1,52 @@ +"""Debug events handler: test [un-]load modules notification""" + +import unittest +import target +import pykd +import fnmatch +import testutils + +class ModuleLoadHandler(pykd.eventHandler): + """Track load/unload module implementation""" + def __init__(self, moduleMask): + pykd.eventHandler.__init__(self) + + self.moduleMask = moduleMask.lower() + + self.wasLoad = 0 + self.wasUnload = False + + def onLoadModule(self, module): + """Load module handler""" + + if ( fnmatch.fnmatch(module.name().lower(), self.moduleMask) ): + self.wasLoad = module.begin() + + return pykd.DEBUG_STATUS_NO_CHANGE + + def onUnloadModule(self, modBase): + """Unload module handler""" + + if ( self.wasLoad and (self.wasLoad == modBase) ): + self.wasUnload = True + + return pykd.DEBUG_STATUS_NO_CHANGE + +class EhLoadTest(unittest.TestCase): + """Unit tests of [un-]load modules notification""" + + def testLoadUnload(self): + """Start new process and track loading and unloading modules""" + pykd.startProcess(target.appPath + " -testLoadUnload") + with testutils.ContextCallIt( pykd.killProcess ) as contextCallIt: + modLoadHandler = ModuleLoadHandler( "*Iphlpapi*" ) + with testutils.ContextCallIt( getattr(modLoadHandler, "reset") ) as resetEventHandler: + try: + while True: + pykd.go() + except pykd.WaitEventException: + pass + + self.assertTrue(modLoadHandler.wasLoad) + self.assertTrue(modLoadHandler.wasUnload) + diff --git a/test/scripts/ehstatustest.py b/test/scripts/ehstatustest.py new file mode 100644 index 0000000..440decf --- /dev/null +++ b/test/scripts/ehstatustest.py @@ -0,0 +1,41 @@ +"""Execution status event test""" + +import unittest +import target +import pykd +import testutils + +class StatusChangeHandler(pykd.eventHandler): + + def __init__(self): + pykd.eventHandler.__init__(self) + self.breakCount = 0 + self.goCount = 0 + self.noDebuggee = 0 + + def onExecutionStatusChange(self, executionStatus): + if executionStatus == pykd.executionStatus.Break: + self.breakCount += 1 + if executionStatus == pykd.executionStatus.Go: + self.goCount += 1 + if executionStatus == pykd.executionStatus.NoDebuggee: + self.noDebuggee += 1 + + +class EhStatusTest(unittest.TestCase): + """Execution status event test""" + + def testException(self): + """Start new process and track exceptions""" + _locProcessId = pykd.startProcess( target.appPath + " -testChangeStatus" ) + with testutils.ContextCallIt( testutils.KillProcess(_locProcessId) ) as killStartedProcess : + + pykd.go() #skip initial break + + statusChangeHandler = StatusChangeHandler() + + self.assertRaises(pykd.WaitEventException, testutils.infGo) + + self.assertEqual( 2, statusChangeHandler.breakCount ) + self.assertEqual( 1, statusChangeHandler.noDebuggee ) + self.assertEqual( statusChangeHandler.breakCount + statusChangeHandler.noDebuggee , statusChangeHandler.goCount ) diff --git a/test/scripts/ehsymbolstest.py b/test/scripts/ehsymbolstest.py new file mode 100644 index 0000000..7509b7d --- /dev/null +++ b/test/scripts/ehsymbolstest.py @@ -0,0 +1,45 @@ +"""Execution symbols state event test""" + +import unittest +import target +import pykd +import testutils + +class SymbolsStateHandler(pykd.eventHandler): + def __init__(self, modBase): + pykd.eventHandler.__init__(self) + self._modBase = modBase + self.modNames = set() + self.unloadModuleTrigged = False + self.unloadAllModulesTrigged = False + + def onSymbolsLoaded(self, modBase): + if modBase: + self.modNames.add( pykd.module(modBase).name() ) + + def onSymbolsUnloaded(self, modBase): + if not modBase: + self.unloadAllModulesTrigged = True + elif self._modBase == modBase: + self.unloadModuleTrigged = True + +class EhSymbolsTest(unittest.TestCase): + """Execution symbols state event test""" + + def testChangeSymbolsState(self): + """Start new process and track change symbols exception""" + _locProcessId = pykd.startProcess( target.appPath + " -testLoadUnload" ) + with testutils.ContextCallIt( testutils.KillProcess(_locProcessId) ) as killStartedProcess: + + mod = pykd.module("targetapp") + symbolsStateHandler = SymbolsStateHandler( mod.begin() ) + + pykd.dbgCommand(".reload /u targetapp.exe") + self.assertTrue( symbolsStateHandler.unloadModuleTrigged ) + + pykd.dbgCommand(".reload /u") + self.assertTrue( symbolsStateHandler.unloadAllModulesTrigged ) + + self.assertRaises(pykd.WaitEventException, testutils.infGo) + + self.assertTrue( "iphlpapi" in symbolsStateHandler.modNames ) diff --git a/test/scripts/eventtest.py b/test/scripts/eventtest.py new file mode 100644 index 0000000..5c179dc --- /dev/null +++ b/test/scripts/eventtest.py @@ -0,0 +1,25 @@ + +import unittest +import target +import pykd + +class handler( pykd.eventHandler ): + + def __init__(self): + pykd.eventHandler.__init__(self) + self.counter=0 + + def onException(self, param): + self.counter += 1 + return pykd.DEBUG_STATUS_NO_CHANGE + + def onExecutionStatusChange(self,status): + print status + +class EventTest( unittest.TestCase ): + + def testDebugBreak( self ): + h = handler() + pykd.go() + pykd.go() + self.assertEqual( 2, h.counter ) diff --git a/test/scripts/intbase.py b/test/scripts/intbase.py new file mode 100644 index 0000000..557fc9e --- /dev/null +++ b/test/scripts/intbase.py @@ -0,0 +1,173 @@ + +import unittest +import target +from pykd import intBase + +class IntBaseTest( unittest.TestCase ): + + def testCtor( self ): + a = intBase(0xFF) + a = intBase(0xFFFF) + a = intBase(0xFFFFFFFF) + a = intBase(0x8000000000000000) + a = intBase(0xFFFFFFFFFFFFFFFF) + a = intBase(-20) + a = intBase(-2000) + a = intBase(-200000) + a = intBase(-20000000000) + a = intBase(-0xFFFFFFFFFFFFFFFF ) + a = intBase( True ) + + def testEq( self ): + self.assertTrue( 0xFF == intBase(0xFF) and intBase(0xFF) == 0xFF ) + self.assertTrue( 0xFFFF == intBase(0xFFFF) and 0xFFFF == intBase(0xFFFF) ) + self.assertTrue( 0xFFFFFFFF == intBase(0xFFFFFFFF) and intBase(0xFFFFFFFF) == 0xFFFFFFFF ) + self.assertTrue( 0x8000000000000000 == intBase(0x8000000000000000) ) + self.assertTrue( 0xFFFFFFFFFFFFFFFF == intBase(0xFFFFFFFFFFFFFFFF) ) + self.assertTrue( -20 == intBase(-20) ) + self.assertTrue( -2000 == intBase(-2000) ) + self.assertTrue( -0x7FFFFFFF == intBase(-0x7FFFFFFF) ) + self.assertTrue( -20000000000 == intBase(-20000000000) ) + self.assertTrue( -0x8000000000000000 == intBase(-0x8000000000000000) ) + self.assertTrue( intBase(0x20L) == intBase(0x20) ) + self.assertTrue( True == intBase(True) ) + self.assertTrue( False == intBase(0) ) + self.assertTrue( True == intBase(1) ) + self.assertTrue( intBase(1) == intBase(1) ) + + def testNe( self ): + self.assertTrue( 0xFE != intBase(0xFF) ) + self.assertTrue( 0xFF00 != intBase(0xFFFF) ) + self.assertTrue( 0xFFFFFF88 != intBase(0xFFFFFFFF) ) + self.assertTrue( 0x8000000000000000 - 1 != intBase(0x8000000000000000) ) + self.assertTrue( 0xFFFFFFFFFFFFFFFF - 1 != intBase(0xFFFFFFFFFFFFFFFF) ) + self.assertTrue( -20 + 1 != intBase(-20) ) + self.assertTrue( -2000 + 1 != intBase(-2000) ) + self.assertTrue( -20000000000 + 1 != intBase(-20000000000) ) + self.assertTrue( -0x8000000000000000 - 1 != intBase(-0x8000000000000000) ) + self.assertTrue( intBase(1) != intBase(2) ) + + def testLtGt( self ): + self.assertTrue( 0xFE < intBase(0xFF) and intBase(0xFE) < 0xFF ) + self.assertFalse( -99 < intBase(-100) and intBase(-99) < - 100 ) + self.assertTrue( 0xFFFFFFFFFFFFFFFE < intBase(0xFFFFFFFFFFFFFFFF) ) + self.assertFalse(0xFFFFFFFFFFFFFFFF < intBase(0xFFFFFFFFFFFFFFFE) ) + self.assertTrue( intBase(0xFFFFFFFFFFFFFFFE) < 0xFFFFFFFFFFFFFFFF ) + self.assertTrue( intBase(1) < intBase(2) ) + + def testLeGe( self ): + self.assertTrue( 0xFE <= intBase(0xFF) and intBase(0xFE) <= 0xFF ) + self.assertTrue( 0xFF <= intBase(0xFF) ) + self.assertFalse( -99 <= intBase(-100) and intBase(-99) <= - 100 ) + self.assertTrue( 0xFFFFFFFFFFFFFFFE <= intBase(0xFFFFFFFFFFFFFFFF) ) + self.assertFalse(0xFFFFFFFFFFFFFFFF <= intBase(0xFFFFFFFFFFFFFFFE) ) + self.assertTrue( intBase(0xFFFFFFFFFFFFFFFF) <= 0xFFFFFFFFFFFFFFFF ) + self.assertFalse( intBase(1) >= intBase(2) ) + + def testAdd( self ): + self.assertEqual( 10, intBase(5) + 5 ) + self.assertEqual( 10, 5 + intBase(5) ) + a = 10 + a += intBase(10) + self.assertEqual( 20, a ) + self.assertEqual( -20, intBase(-10) + (-10) ) + self.assertEqual( 10, intBase(-10) + 20 ) + self.assertEqual( 0x7fffffffffffffff + 1, intBase(0x7fffffffffffffff) + 1) + self.assertEqual( -0x8000000000000000 + 10, intBase(-0x8000000000000000) + 10 ) + self.assertEqual( 0, intBase(-0x8000000000000000) + 0x8000000000000000 ) + self.assertEqual( 5, intBase(3) + intBase(2) ) + + def testSub( self ): + self.assertEqual( 0, intBase(5) - 5 ) + self.assertEqual( 10, 15 - intBase(5) ) + a = 10 + a -= intBase(5) + self.assertEqual( 5, a ) + self.assertEqual( -20, intBase(-10) -10 ) + self.assertEqual( -10, 10 - intBase(20) ) + self.assertEqual( -0xFFFFFFFF - 1, intBase(-0xFFFFFFFF) - 1 ) + self.assertEqual( 5, intBase(7) - intBase(2) ) + + def testMul( self ): + self.assertEqual( 4, intBase(2) * 2 ) + self.assertEqual( 4, 2 * intBase(2) ) + self.assertEqual( -4, 2 * intBase(-2) ) + self.assertEqual( 4, -2 * intBase(-2) ) + self.assertEqual( 0x7fffffffffffffff * 2, intBase(0x7fffffffffffffff) * 2) + self.assertEqual( 0x80000000*2, intBase(0x80000000)*2 ) + self.assertEqual( -0x80000000*2, 2 * intBase(-0x80000000)) + self.assertEqual( 14, intBase(7)*intBase(2) ) + + def testDiv( self ): + self.assertEqual( 1, intBase(2) / 2 ) + self.assertEqual( 2, 5 / intBase(2) ) + self.assertEqual( -1, 2 / intBase(-2) ) + self.assertEqual( 1, -2 / intBase(-2) ) + self.assertEqual( 3, intBase(7)/intBase(2) ) + + try: + -2 / intBase(0) + self.assertTrue( False ) + except ZeroDivisionError: + self.assertTrue( True ) + + try: + intBase(2)/0 + self.assertTrue( False ) + except ZeroDivisionError: + self.assertTrue( True ) + + try: + intBase(0)/intBase(0) + self.assertTrue( False ) + except ZeroDivisionError: + self.assertTrue( True ) + + def testMod( self ): + self.assertEqual( 1, intBase(3) % 2 ) + self.assertEqual( 0, intBase(3) % 3 ) + self.assertEqual( 1, 3 % intBase(2) ) + self.assertEqual( 0, 3 % intBase(3) ) + self.assertEqual( 2, intBase(5) % intBase(3) ) + + def testShift( self ): + self.assertEqual( 0xFFFFFFFF >> 8, intBase(0xFFFFFFFF) >> 8 ) + self.assertEqual( 0x00FFFFFF << 8, intBase(0x00FFFFFF) << 8 ) + self.assertEqual( 0xFFFFFFFF >> 8, 0xFFFFFFFF >> intBase(8) ) + self.assertEqual( 0x00FFFFFF << 8, 0x00FFFFFF << intBase(8) ) + + def testAnd( self ): + self.assertEqual( 0xFFFFFFFF & 0xFFFF, intBase(0xFFFFFFFF) & 0xFFFF ) + self.assertEqual( 0xFFFFFFFF & 0xFFFF, 0xFFFFFFFF & intBase(0xFFFF) ) + self.assertEqual( -0xFFFFFFFF & 0xFFFF, intBase(-0xFFFFFFFF) & 0xFFFF ) + self.assertEqual( -0xFFFFFFFF & 0xFFFF, -0xFFFFFFFF & intBase(0xFFFF) ) + + def testOr( self ): + self.assertEqual( 0xFFFF0000 | 0xFFFF, intBase(0xFFFF0000) | 0xFFFF ) + self.assertEqual( 0xFFFF0000 | 0xFFFF, 0xFFFF0000 | intBase(0xFFFF) ) + self.assertEqual( -0xFFFF0000 | 0xFFFF, intBase(-0xFFFF0000) | 0xFFFF ) + self.assertEqual( -0xFFFF0000 | 0xFFFF, -0xFFFF0000 | intBase(0xFFFF) ) + + def testXor( self ): + self.assertEqual( 0xFFFFFFFF ^ 0xFFFF, intBase(0xFFFFFFFF) ^ 0xFFFF ) + self.assertEqual( 0xFFFFFFFF ^ 0xFFFF, 0xFFFFFFFF ^ intBase(0xFFFF) ) + self.assertEqual( -0xFFFFFFFF ^ 0xFFFF, intBase(-0xFFFFFFFF) ^ 0xFFFF ) + self.assertEqual( -0xFFFFFFFF ^ 0xFFFF, -0xFFFFFFFF ^ intBase(0xFFFF) ) + + def testUnary( self ): + self.assertEqual( -0xFFFFFFFF, -intBase(0xFFFFFFFF) ) + self.assertEqual( 0xFFFFFFFF, +intBase(0xFFFFFFFF) ) + self.assertEqual( 0, ~intBase(0xFFFFFFFF) ) + + def testLongConvert( self ): + self.assertEqual( "100", "%d" % intBase(100) ) + self.assertEqual( "FFFF", "%X" % intBase(0xFFFF) ) + self.assertEqual( "-70000000000", "%d" % intBase(-70000000000) ) + self.assertEqual( "FFFFFFFFFFFFFF", "%X" % intBase(0xFFFFFFFFFFFFFF) ) + self.assertEqual( "0", "%d" % intBase(False) ) + + def testConvert( self ): + self.assertEqual( "100", "%d" % intBase(100) ) + self.assertEqual( "64", "%x" % intBase(100) ) + + \ No newline at end of file diff --git a/test/scripts/localstest.py b/test/scripts/localstest.py new file mode 100644 index 0000000..403e748 --- /dev/null +++ b/test/scripts/localstest.py @@ -0,0 +1,49 @@ +"""Local variables tests""" + +import unittest +import target +import pykd +import testutils + + +def testEnumWindowsProc1Locals(testCase, locals): + testCase.assertNotEqual( 0, locals["hWindow"] ) + DataIsParam = 3 + testCase.assertEqual( DataIsParam, locals["hWindow"].dataKind() ) + + testCase.assertEqual( 6, locals["lParam"] ) + testCase.assertEqual( DataIsParam, locals["lParam"].dataKind() ) + + DataIsLocal = 1 + testCase.assertNotEqual( 0, locals["dwProccessId"] ) + testCase.assertEqual( DataIsLocal, locals["dwProccessId"].dataKind() ) + + DataIsStaticLocal = 2 + testCase.assertNotEqual( 0, locals["staticVar"] ) + testCase.assertEqual( DataIsStaticLocal, locals["staticVar"].dataKind() ) + + testCase.assertEqual( locals["dwProccessId"] + 1, locals["staticVar"] ) + + +class LocalVarsTest(unittest.TestCase): + def testLocalVariable(self): + """Start new process and test local variables""" + _locProcessId = pykd.startProcess( target.appPath + " -testEnumWindows" ) + with testutils.ContextCallIt( testutils.KillProcess(_locProcessId) ) as killStartedProcess : + pykd.go() # initial breakpoint -> wmain + pykd.go() # wmain -> targetapp!EnumWindowsProc1 + + testEnumWindowsProc1Locals(self, pykd.getLocals()) + + pykd.go() # targetapp!EnumWindowsProc1 -> targetapp!functionCalledFromEnumWindowsProc1 + testEnumWindowsProc1Locals(self, pykd.getStack()[1].locals ) + + pykd.go() # targetapp!EnumWindowsProc1 -> targetapp!EnumWindowsProc2 + locals = pykd.getLocals() + self.assertEqual( len(locals), 2 ) + self.assertTrue( locals[0] == 7 or locals[1] == 7 ) + + funcParams = pykd.getParams() + self.assertEqual( len(funcParams), 2 ) + self.assertTrue( funcParams[0] == 7 or funcParams[1] == 7 ) + diff --git a/test/scripts/memtest.py b/test/scripts/memtest.py new file mode 100644 index 0000000..08a14b0 --- /dev/null +++ b/test/scripts/memtest.py @@ -0,0 +1,123 @@ +# +# +# + +import unittest +import target +import pykd +import math + +class MemoryTest( unittest.TestCase ): + + def testLoadChars( self ): + s = pykd.loadChars( target.module.helloStr, 5 ) + self.assertEqual( "Hello", s ) + + def testLoadWChars( self ): + s = pykd.loadWChars( target.module.helloWStr, 5 ) + self.assertEqual( "Hello", s ) + + def testLoadBytes( self ): + ucharArray = pykd.loadBytes( target.module.ucharArray, 5 ) + testArray = [ 0, 10, 0x78, 128, 0xFF ] + self.assertEqual( 5, len(ucharArray) ) + self.assertEqual( 0, len( [ ucharArray[i] for i in xrange(5) if ucharArray[i] != testArray[i] ] ) ) + + def testLoadWords( self ): + loadArray = pykd.loadWords( target.module.ushortArray, 5 ) + testArray = [ 0, 10, 0xFF, 0x8000, 0xFFFF ] + self.assertEqual( len(testArray), len(loadArray) ) + self.assertEqual( 0, len( [ loadArray[i] for i in xrange(len(testArray)) if loadArray[i] != testArray[i] ] ) ) + + def testLoadDWords( self ): + loadArray = pykd.loadDWords( target.module.ulongArray, 5 ) + testArray = [ 0, 0xFF, 0x8000, 0x80000000, 0xFFFFFFFF ] + self.assertEqual( len(testArray), len(loadArray) ) + self.assertEqual( 0, len( [ loadArray[i] for i in xrange(len(testArray)) if loadArray[i] != testArray[i] ] ) ) + + def testLoadQWords( self ): + loadArray = pykd.loadQWords( target.module.ulonglongArray, 5 ) + testArray = [ 0, 0xFF, 0xFFFFFFFF, 0x8000000000000000, 0xFFFFFFFFFFFFFFFF ] + self.assertEqual( len(testArray), len(loadArray) ) + self.assertEqual( 0, len( [ loadArray[i] for i in xrange(len(testArray)) if loadArray[i] != testArray[i] ] ) ) + + def testLoadSignBytes( self ): + charArray = pykd.loadSignBytes( target.module.ucharArray, 5 ) + testArray = [ 0, 10, 0x78, -128, -1 ] + self.assertEqual( 5, len(charArray) ) + self.assertEqual( 0, len( [ charArray[i] for i in xrange(len(testArray)) if charArray[i] != testArray[i] ] ) ) + + def testLoadSignWords( self ): + loadArray = pykd.loadSignWords( target.module.ushortArray, 5 ) + testArray = [ 0, 10, 255, -32768, -1 ] + self.assertEqual( len(testArray), len(loadArray) ) + self.assertEqual( 0, len( [ loadArray[i] for i in xrange(len(testArray)) if loadArray[i] != testArray[i] ] ) ) + + def testLoadSignDWords( self ): + loadArray = pykd.loadSignDWords( target.module.ulongArray, 5 ) + testArray = [0, 255, 32768, -2147483648, -1] + self.assertEqual( len(testArray), len(loadArray) ) + self.assertEqual( 0, len( [ loadArray[i] for i in xrange(len(testArray)) if loadArray[i] != testArray[i] ] ) ) + + def testLoadSignQWords( self ): + loadArray = pykd.loadSignQWords( target.module.ulonglongArray, 5 ) + testArray = [0, 255, 4294967295L, -9223372036854775808L, -1] + self.assertEqual( len(testArray), len(loadArray) ) + self.assertEqual( 0, len( [ loadArray[i] for i in xrange(len(testArray)) if loadArray[i] != testArray[i] ] ) ) + + def testPtrRead( self ): + self.assertEqual( 0x80, pykd.ptrByte( target.module.g_bigValue ) ) + self.assertEqual( 0x8080, pykd.ptrWord( target.module.g_bigValue ) ) + self.assertEqual( 0x80808080, pykd.ptrDWord( target.module.g_bigValue ) ) + self.assertEqual( 0x8080808080808080, pykd.ptrQWord( target.module.g_bigValue ) ) + self.assertEqual( -128, pykd.ptrSignByte( target.module.g_bigValue ) ) + self.assertEqual( -32640, pykd.ptrSignWord( target.module.g_bigValue ) ) + self.assertEqual( -2139062144, pykd.ptrSignDWord( target.module.g_bigValue ) ) + self.assertEqual( -9187201950435737472, pykd.ptrSignQWord( target.module.g_bigValue ) ) + + def testCompare( self ): + self.assertTrue( pykd.compareMemory( target.module.helloStr, pykd.ptrPtr(target.module.strArray), 5 ) ) + self.assertFalse( pykd.compareMemory( target.module.helloStr, target.module.helloWStr, 5 ) ) + + def testCStr( self ): + self.assertEqual( 'Hello', pykd.loadCStr( target.module.helloStr ) ) + self.assertEqual( u'Hello', pykd.loadWStr( target.module.helloWStr ) ) + + def testBigCStr( self ): + self.assertEqual( 0x2000, len( pykd.loadCStr( pykd.ptrPtr( target.module.bigCStr ) ) ) ) + self.assertEqual( 0x2000, len( pykd.loadWStr( pykd.ptrPtr( target.module.bigWStr ) ) ) ) + + def testVaValid( self ): + self.assertTrue( pykd.isValid( target.module.begin() ) ) + self.assertFalse( pykd.isValid( 0 ) ) + self.assertFalse( pykd.isValid( 0xDEADBEAF ) ) + + def testPtrList( self ): + lst = pykd.loadPtrList( target.module.g_listHead ) + self.assertEqual( 3, len( lst ) ) + + def testPtrArray( self ): + lst = pykd.loadPtrs( target.module.arrIntMatrixPtrs, 3 ) + self.assertEqual( 3, len( lst ) ) + + def testInvalidAddr( self ): + try: + pykd.loadSignBytes( 0xDEADBEEF, 5 ) + except pykd.MemoryException: + self.assertTrue( True ) + + def testPtrFloat(self): + self.assertTrue( math.fabs( pykd.ptrFloat( target.module.g_float) - 5.123456 ) < 0.001 ) + self.assertTrue( math.fabs( pykd.ptrDouble( target.module.g_double) - 5.1234567891 ) < 0.0000001 ) + + def testLoadFloats(self): + testArray = [ 1.0, 2.001, -3.0004 ]; + readArray = pykd.loadFloats( target.module.floatArray, 3 ); + for i in range(0,3): + self.assertTrue( math.fabs( testArray[i] - readArray[i] ) < 0.001 ) + + def testLoadDoubles(self): + testArray = [ 1.0, 2.0000001, -3.0000004 ]; + readArray = pykd.loadDoubles( target.module.doubleArray, 3 ); + for i in range(0,3): + self.assertTrue( math.fabs( testArray[i] - readArray[i] ) < 0.0000001 ) diff --git a/test/scripts/moduletest.py b/test/scripts/moduletest.py new file mode 100644 index 0000000..1b960b2 --- /dev/null +++ b/test/scripts/moduletest.py @@ -0,0 +1,110 @@ +# +# +# + +import unittest +import target +import pykd +import re + +class ModuleTest( unittest.TestCase ): + + def testCtor( self ): + self.assertEqual( target.module.name(), pykd.module(target.module.begin() ).name() ) + self.assertEqual( target.module.name(), pykd.module(target.module.name() ).name() ) + + def testMiscellaneous( self ): + self.assertFalse( target.module.unloaded() ) + self.assertTrue( target.module.um() ) + + def testName( self ): + self.assertEqual( target.moduleName, target.module.name() ) + + def testSize( self ): + self.assertNotEqual( 0, target.module.size() ) + self.assertTrue( pykd.isValid( target.module.begin() + target.module.size() - 1) ) + + def testBegin( self ): + self.assertNotEqual( 0, target.module.begin() ) + self.assertEqual( target.module.begin(), target.module ) + self.assertEqual( target.module.begin() + 100, target.module + 100 ) + + def testEnd( self ): + self.assertEqual( target.module.size(), target.module.end() - target.module.begin() ) + self.assertTrue( pykd.isValid( target.module.end() - 1) ) + + def testPdb( self ): + self.assertNotEqual( "", target.module.symfile() ) + + def testImage( self ): + self.assertEqual( target.module.name() + ".exe", target.module.image() ) + + def testFindModule( self ): + self.assertRaises( pykd.BaseException, pykd.module, target.module.begin() - 0x10 ) + + self.assertNotEqual( None, pykd.module( target.module.begin() ) ) + self.assertNotEqual( None, pykd.module( target.module.begin() + 0x10) ) + + self.assertRaises( pykd.BaseException, pykd.module, target.module.end() ) + self.assertRaises( pykd.BaseException, pykd.module, target.module.end() + 0x10 ) + + def testSymbol( self ): + self.assertEqual( target.module.rva("FuncWithName0"), target.module.offset("FuncWithName0") - target.module.begin() ) + self.assertEqual( target.module.rva("FuncWithName0"), target.module.FuncWithName0 - target.module.begin() ) + self.assertEqual( target.module.rva("FuncWithName0"), pykd.getOffset( target.module.name() + "!FuncWithName0") - target.module.begin() ) + + def testFindSymbol( self ): + self.assertEqual( "FuncWithName0", target.module.findSymbol( target.module.offset("FuncWithName0") ) ) + self.assertEqual( "_FuncWithName2", target.module.findSymbol( target.module.offset("_FuncWithName2") ) ) + self.assertEqual( "targetapp!FuncWithName0", pykd.findSymbol( target.module.offset("FuncWithName0") ) ) + self.assertEqual( "targetapp!_FuncWithName2", pykd.findSymbol( target.module.offset("_FuncWithName2") ) ) + self.assertEqual( "_FuncWithName2+10", target.module.findSymbol( target.module.offset("_FuncWithName2") + 0x10 ) ) + self.assertEqual( "_FuncWithName2", target.module.findSymbol( target.module.offset("_FuncWithName2") + 0x10, showDisplacement = False ) ) + self.assertEqual( "targetapp!_FuncWithName2+10", pykd.findSymbol( target.module.offset("_FuncWithName2") + 0x10 ) ) + self.assertEqual( "targetapp!_FuncWithName2", pykd.findSymbol( target.module.offset("_FuncWithName2") + 0x10, showDisplacement = False ) ) + + def testFindSymbolAndDisp( self ): + vaFuncWithName0 = target.module.offset("FuncWithName0") + self.assertEqual( ("FuncWithName0", 0), target.module.findSymbolAndDisp(vaFuncWithName0) ) + self.assertEqual( ("FuncWithName0", 2), target.module.findSymbolAndDisp(vaFuncWithName0+2) ) + self.assertEqual( ("targetapp!FuncWithName0", 0), pykd.findSymbolAndDisp(vaFuncWithName0) ) + self.assertEqual( ("targetapp!FuncWithName0", 2), pykd.findSymbolAndDisp(vaFuncWithName0+2) ) + + def testType( self ): + self.assertEqual( "structTest", target.module.type("structTest").name() ); + self.assertEqual( "structTest", target.module.type("g_structTest").name() ); + + def testSourceFile( self ): + fileName = pykd.getSourceFile(target.module.FuncWithName0 ) + self.assertTrue( re.search('targetapp\\.cpp', fileName ) ) + fileName, lineNo, displacement = pykd.getSourceLine( target.module.FuncWithName0 + 2) + self.assertEqual( 421, lineNo ) + self.assertTrue( re.search('targetapp\\.cpp', fileName ) ) + self.assertEqual( 2, displacement ) + fileName, lineNo, displacement = pykd.getSourceLine() + self.assertEqual( 698, lineNo ) + + def testEnumSymbols( self ): + lst = target.module.enumSymbols() + self.assertNotEqual( 0, len(lst) ) + lst = target.module.enumSymbols("hello*Str") + self.assertEqual( 2, len(lst) ) + lst = target.module.enumSymbols( "g_const*Value") + self.assertEqual( 2, len(lst) ) + lst = target.module.enumSymbols( "*FuncWithName?") + self.assertEqual( 3, len(lst) ) + lst = target.module.enumSymbols( "*virtFunc*") + self.assertNotEqual( 0, len(lst) ) + lst = target.module.enumSymbols( "classChild" ) + self.assertEqual( 0, len(lst) ) + + def testGetTypes( self ): + lst1 = target.module.getUdts() + self.assertNotEqual( 0, len(lst1) ) + self.assertTrue( "classChild" in lst1 ) + self.assertTrue( "classBase" in lst1 ) + self.assertTrue( "structTest" in lst1 ) + + lst2 = target.module.getEnums() + self.assertNotEqual( 0, len(lst2) ) + self.assertTrue( "enumType" in lst2 ) diff --git a/test/scripts/mspdbtest.py b/test/scripts/mspdbtest.py new file mode 100644 index 0000000..da87001 --- /dev/null +++ b/test/scripts/mspdbtest.py @@ -0,0 +1,45 @@ +"""Public microsoft symbols tests""" + +import unittest +import pykd +import os + +class PeFileAsDumpLoader: + """Load/unload PE-file from System as crash dump file""" + def __init__(self, fileName): + self._fileName = fileName + + def __enter__(self): + pykd.loadDump(self._fileName) + + def __exit__(self, exc_type, exc_value, exc_tb): + pykd.detachProcess() + +class MsPdbTest(unittest.TestCase): + """Public Microsoft symbols tests""" + + def testSymbolNameAddress(self): + """Lookup symbol by name/address""" + with PeFileAsDumpLoader( os.path.join(os.environ["WINDIR"], r"System32\ole32.dll") ): + mod = pykd.module("ole32") + print "\n" + str( mod ) + + targetSymAddr = mod.offset("CPackagerMoniker::Create") + self.assertNotEqual( 0, targetSymAddr ) + self.assertEqual( "CPackagerMoniker::Create", mod.findSymbol(targetSymAddr) ) + + targetSymAddr = mod.offset("CoInitialize") + self.assertNotEqual( 0, targetSymAddr ) + self.assertEqual( "CoInitialize", mod.findSymbol(targetSymAddr) ) + + with PeFileAsDumpLoader( os.path.join(os.environ["WINDIR"], r"System32\authz.dll") ): + mod = pykd.module("authz") + print "\n" + str( mod ) + + targetSymAddr = mod.offset("AuthzpDefaultAccessCheck") + self.assertNotEqual( 0, targetSymAddr ) + self.assertEqual( "AuthzpDefaultAccessCheck", mod.findSymbol(targetSymAddr) ) + + targetSymAddr = mod.offset("AuthzAccessCheck") + self.assertNotEqual( 0, targetSymAddr ) + self.assertEqual( "AuthzAccessCheck", mod.findSymbol(targetSymAddr) ) diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py new file mode 100644 index 0000000..aa2535b --- /dev/null +++ b/test/scripts/pykdtest.py @@ -0,0 +1,81 @@ +# +# +# + +import sys +import os +import unittest + +# Dynamically append current pykd.pyd path to PYTHONPATH +sys.path.insert(0, os.path.dirname(sys.argv[1])) + +import pykd + +import target + +import intbase +import memtest +import moduletest +import typeinfo +import typedvar +import regtest +import mspdbtest +import localstest +import customtypestest +import ehexcepttest +import ehstatustest +import ehsymbolstest + +class StartProcessWithoutParamsTest(unittest.TestCase): + def testStart(self): + target.processId = pykd.startProcess( target.appPath ) + target.module = pykd.module( target.moduleName ) + target.module.reload(); + print "\n" + str( pykd.getSystemVersion() ) + pykd.go() + +class TerminateProcessTest(unittest.TestCase): + def testKill(self): + pykd.killProcess( target.processId ) + pykd.detachProcess( target.processId ) + +def getTestSuite( singleName = "" ): + if singleName == "": + return unittest.TestSuite( + [ + unittest.TestLoader().loadTestsFromTestCase( StartProcessWithoutParamsTest ), + # *** Test without start/kill new processes + unittest.TestLoader().loadTestsFromTestCase( intbase.IntBaseTest ), + unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ), + unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ), + unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), + unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ), + unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ), + unittest.TestLoader().loadTestsFromTestCase( customtypestest.CustomTypesTest ), + # ^^^ + unittest.TestLoader().loadTestsFromTestCase( TerminateProcessTest ), + + unittest.TestLoader().loadTestsFromTestCase( mspdbtest.MsPdbTest ), + unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest ), + unittest.TestLoader().loadTestsFromTestCase( ehexcepttest.EhExceptionTest ), + unittest.TestLoader().loadTestsFromTestCase( ehstatustest.EhStatusTest ), + unittest.TestLoader().loadTestsFromTestCase( ehsymbolstest.EhSymbolsTest ), + ] ) + else: + return unittest.TestSuite( + [ + unittest.TestLoader().loadTestsFromTestCase( StartProcessWithoutParamsTest ), + unittest.TestLoader().loadTestsFromName( singleName ), + unittest.TestLoader().loadTestsFromTestCase( TerminateProcessTest ) + ] ) + +if __name__ == "__main__": + + print "\nTesting PyKd ver. " + pykd.version + + target.appPath = sys.argv[1] + target.moduleName = os.path.splitext(os.path.basename(target.appPath))[0] + + unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite() ) + + diff --git a/test/scripts/regtest.py b/test/scripts/regtest.py new file mode 100644 index 0000000..0398598 --- /dev/null +++ b/test/scripts/regtest.py @@ -0,0 +1,50 @@ + +import unittest +import target +import pykd + +class CpuRegTest( unittest.TestCase ): + + def testCtor(self): + if pykd.is64bitSystem(): + pykd.reg("rax") + else: + pykd.reg("eax") + + pykd.reg( 0 ) + + def testFormat(self): + self.assertEqual( "%d" % int(pykd.reg(0)), "%d" % pykd.reg(0) ) + self.assertEqual( "%x" % int(pykd.reg(0)), "%x" % pykd.reg(0) ) + + def testGpr(self): + if pykd.is64bitSystem(): + pykd.reg("rax") + pykd.reg("rbx") + pykd.reg("rcx") + pykd.reg("rdx") + pykd.reg("rdi") + pykd.reg("rsi") + pykd.reg("rbp") + pykd.reg("rsp") + pykd.reg("rip") + else: + pykd.reg("eax") + pykd.reg("ebx") + pykd.reg("ecx") + pykd.reg("edx") + pykd.reg("edi") + pykd.reg("esi") + pykd.reg("ebp") + pykd.reg("esp") + pykd.reg("eip") + + + def testFloatRegister(self): + "TODO: support float point regsiters" + self.assertRaises( pykd.BaseException, pykd.reg, "st0" ) + + def testMmxRegister(self): + "TODO: support MMX regsiters" + self.assertRaises( pykd.BaseException, pykd.reg, "mmx0" ) + diff --git a/test/scripts/synsymtest.py b/test/scripts/synsymtest.py new file mode 100644 index 0000000..ee54df0 --- /dev/null +++ b/test/scripts/synsymtest.py @@ -0,0 +1,81 @@ +"""Synthetic symbols tests""" + +import unittest +import target +import pykd + +class SynSymTest(unittest.TestCase): + """Unit tests of synthetic symbols""" + + def testAdd(self): + """Add new synthetic symbol""" + pykd.addSynSymbol( + target.module.offset("FuncWithName0")-1, 1, "synSym1") + self.assertEqual( + target.module.offset("FuncWithName0")-1, + target.module.offset("synSym1")) + + def testDel(self): + """Remove synthetic symbol""" + pykd.addSynSymbol( + target.module.offset("FuncWithName0")-2, 1, "synSym2") + self.assertEqual( + pykd.delSynSymbol( target.module.offset("synSym2") ), 1 ) + + exceptionOccurred = True + try: + target.module.rva("synSym2") + exceptionOccurred = False + except pykd.BaseException: + pass + self.assertTrue(exceptionOccurred) + + def testDelAll(self): + """Remove all synthetic symbols""" + pykd.addSynSymbol( + target.module.offset("FuncWithName0")-3, 1, "synSym3") + pykd.delAllSynSymbols() + + exceptionOccurred = True + try: + target.module.rva("synSym3") + exceptionOccurred = False + except pykd.BaseException: + pass + self.assertTrue(exceptionOccurred) + + def testDelByMask(self): + """Remove synthetic symbol by mask""" + pykd.addSynSymbol( + target.module.offset("FuncWithName0")-4, 1, "synSym4") + self.assertTrue( pykd.delSynSymbolsMask( "*", "synSym4" ) >= 1 ) + + exceptionOccurred = True + try: + target.module.rva("synSym4") + exceptionOccurred = False + except pykd.BaseException: + pass + self.assertTrue(exceptionOccurred) + + def testReload(self): + """Restore synthetic symbols after reload module symbols""" + pykd.addSynSymbol( + target.module.offset("FuncWithName0")-5, 1, "synSym5") + target.module.reload() + self.assertEqual( + target.module.offset("FuncWithName0")-5, + target.module.offset("synSym5")) + + def testAddSynSymbolException(self): + """Test of AddSynSymbolException""" + pykd.addSynSymbol( + target.module.offset("FuncWithName0")-6, 1, "synSym6") + + exceptionOccurred = False + try: + pykd.addSynSymbol( + target.module.offset("FuncWithName0")-6, 1, "synSym7") + except pykd.AddSynSymbolException: + exceptionOccurred = True + self.assertTrue(exceptionOccurred) diff --git a/test/scripts/target.py b/test/scripts/target.py new file mode 100644 index 0000000..a464cfe --- /dev/null +++ b/test/scripts/target.py @@ -0,0 +1,17 @@ +# +# +# + +import unittest +import pykd + +appPath = None +module = None +moduleName = None +processId = None + + +#module = None +#moduleName = None +#dbgext = None +#appPath = None diff --git a/test/scripts/testutils.py b/test/scripts/testutils.py new file mode 100644 index 0000000..557285a --- /dev/null +++ b/test/scripts/testutils.py @@ -0,0 +1,30 @@ +"""PyKd test heplers/wrappers""" + +import pykd + +class ContextCallIt: + """Context manager/with statement""" + def __init__(self, callIt): + self.callIt = callIt + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, exc_tb): + try: self.callIt() + except: pass + +class KillProcess: + """Kill process""" + def __init__(self, processId): + self.processId = processId + + def __call__(self): + pykd.killProcess( self.processId ) + pykd.detachProcess( self.processId ) + +def infGo(): + """Infinite pykd.go call""" + while True: + pykd.go() + diff --git a/test/scripts/thrdctxtest.py b/test/scripts/thrdctxtest.py new file mode 100644 index 0000000..158b454 --- /dev/null +++ b/test/scripts/thrdctxtest.py @@ -0,0 +1,33 @@ +"""Tests of thread context""" + +import unittest +import target +import pykd + +class ThreadContextTest( unittest.TestCase ): + def testCurrentThreadContext( self ): + """Some checks of current thread context content""" + ctx = pykd.getContext() +# for reg in ctx: +# regName = "" +# if ctx.processorType() == "X86": +# regName = pykd.diaI386Regs[ reg[0] ] +# else: +# regName = pykd.diaAmd64Regs[ reg[0] ] +# pykd.dprint( "\n" + regName + ": 0x%x " % reg[1]) + self.assertNotEqual( 0, len(ctx) ) + self.assertNotEqual( 0, ctx.ip() ) + self.assertNotEqual( 0, ctx.csp() ) + + def testComplexRegisters( self ): + """Test of "sub-"registers""" + ctx = pykd.getContext() + self.assertEqual( (ctx.get(pykd.CV_REG_AH) << 8) | ctx.get(pykd.CV_REG_AL), ctx.get(pykd.CV_REG_AX) ) + self.assertEqual( ctx.get(pykd.CV_REG_AX), ctx.get(pykd.CV_REG_EAX) & 0xffff ) + if ctx.processorType() == "X64": + self.assertEqual( ctx.get(pykd.CV_REG_EAX), ctx.get(pykd.CV_AMD64_RAX) & 0xffffffff ) + + self.assertEqual( (ctx.get(pykd.CV_REG_DH) << 8) | ctx.get(pykd.CV_REG_DL), ctx.get(pykd.CV_REG_DX) ) + self.assertEqual( ctx.get(pykd.CV_REG_DX), ctx.get(pykd.CV_REG_EDX) & 0xffff ) + if ctx.processorType() == "X64": + self.assertEqual( ctx.get(pykd.CV_REG_EDX), ctx.get(pykd.CV_AMD64_RDX) & 0xffffffff ) diff --git a/test/scripts/typedvar.py b/test/scripts/typedvar.py new file mode 100644 index 0000000..a11edeb --- /dev/null +++ b/test/scripts/typedvar.py @@ -0,0 +1,325 @@ +# +# +# + +import unittest +import target +import pykd + +class TypedVarTest( unittest.TestCase ): + + def testCtor( self ): + tv = target.module.typedVar( "structTest", target.module.g_structTest ) + tv = target.module.typedVar( "g_structTest" ) + + tv = pykd.typedVar( "structTest", target.module.g_structTest ) + tv = pykd.typedVar( target.moduleName + "!structTest", target.module.g_structTest ) + + structTest = target.module.type( "structTest" ) + tv = pykd.typedVar( structTest, target.module.g_structTest ) + + tv = pykd.typedVar( "g_structTest" ) + tv = pykd.typedVar( target.moduleName + "!g_structTest" ) + + def testBaseTypes(self): + self.assertEqual( 1, target.module.typedVar( "g_ucharValue" ) ) + self.assertEqual( 2, target.module.typedVar( "g_ushortValue" ) ) + self.assertEqual( 4, target.module.typedVar( "g_ulongValue" ) ) + self.assertEqual( 8, target.module.typedVar( "g_ulonglongValue" ) ) + self.assertEqual( -1, target.module.typedVar( "g_charValue" ) ) + self.assertEqual( -2, target.module.typedVar( "g_shortValue" ) ) + self.assertEqual( -4, target.module.typedVar( "g_longValue" ) ) + self.assertEqual( -8, target.module.typedVar( "g_longlongValue" ) ) + + def testPtrTo(self): + tvBaseType = pykd.typedVar( pykd.typeInfo("UInt8B").ptrTo(), + target.module.offset("g_pUlonglongValue") ) + self.assertEqual( target.module.typedVar( "g_ulonglongValue" ), + tvBaseType.deref() ) + + tvDiaStruct = pykd.typedVar( target.module.type("structTest").ptrTo(), + target.module.offset("g_structTestPtr") ) + self.assertEqual( 500, tvDiaStruct.deref().m_field1 ) + + customStructTest = pykd.typeBuilder().createStruct("customStructTest", 4) + customStructTest.append("m_field0", pykd.typeInfo("UInt4B")) + customStructTest.append("m_field1", pykd.typeInfo("UInt8B")) + tvCustomStruct = pykd.typedVar( customStructTest.ptrTo(), target.module.offset("g_structTestPtr") ) + self.assertEqual( 500, tvCustomStruct.deref().m_field1 ) + + def testArrayOf(self): + arrayType = pykd.typeInfo("UInt8B").arrayOf(5) + arrayVar = pykd.typedVar( arrayType, target.module.offset("ulonglongArray") ) + self.assertEqual( 0xFF, arrayVar[1] ) + self.assertEqual( 0xFFFFFFFFFFFFFFFF, arrayVar[4] ) + + arrayStructType = pykd.typeInfo("structTest").arrayOf(2) + arrayStructVar = pykd.typedVar( arrayStructType, target.module.offset("g_testArray") ) + self.assertEqual( True, arrayStructVar[0].m_field2 ) + self.assertEqual( 1, arrayStructVar[1].m_field3 ) + + def testConst(self): + self.assertEqual( True, target.module.typedVar( "g_constBoolValue" ) ) + self.assertEqual( 0x5555, target.module.typedVar( "g_constNumValue" ) ) + self.assertEqual( 3, target.module.typedVar( "g_constEnumThree" ) ) + self.assertEqual( 0xffffff, target.module.typedVar( "g_constUlong" ) ) + self.assertEqual( 0xffffff000000, target.module.typedVar( "g_constUlonglong" ) ) + + def testGetAddress( self ): + tv = target.module.typedVar( "structTest", target.module.g_structTest ) + self.assertEqual( tv.getAddress(), target.module.g_structTest ) + + def testGetSize( self ): + tv1 = target.module.typedVar( "structTest", target.module.g_structTest ) + self.assertEqual( 16 + pykd.ptrSize(), tv1.sizeof() ) + tv2 = target.module.typedVar( "structTest[2]", target.module.g_testArray ) + self.assertEqual( tv1.sizeof()*2, tv2.sizeof() ) + + self.assertEqual( pykd.sizeof("g_structTest"), tv1.sizeof() ) + self.assertEqual( pykd.sizeof("g_testArray"), tv2.sizeof() ) + self.assertEqual( pykd.sizeof("g_ucharValue"), 1 ) + + def testByAddress( self ): + tv1 = target.module.typedVar( "structTest", target.module.g_structTest ) + tv2 = target.module.typedVar( tv1.getAddress() ) + self.assertEqual( tv2.getAddress(), tv1.getAddress() ) + + def testStruct(self): + tv1 = target.module.typedVar( "structTest", target.module.g_structTest ) + self.assertEqual( 0, tv1.m_field0 ) + self.assertEqual( 500, tv1.m_field1 ) + self.assertEqual( True, tv1.m_field2 ) + self.assertEqual( 1, tv1.m_field3 ) + + def testPtrField(self): + tv = target.module.typedVar( "g_structTest" ) + self.assertEqual( 0, tv.m_field4 ) + tv1 = target.module.typedVar( "g_structTest1" ) + self.assertEqual( tv.getAddress(), tv1.m_field4 ) + + def testFieldOffset(self): + tv = target.module.typedVar( "g_structTest" ) + self.assertEqual( 0, tv.fieldOffset("m_field0") ) + self.assertEqual( 4, tv.fieldOffset("m_field1") ) + self.assertEqual( 16, tv.fieldOffset("m_field4") ) + + def testArrayField(self): + tv = target.module.typedVar( "g_struct3" ) + self.assertEqual( 2, len(tv.m_arrayField) ) + self.assertEqual( 0, tv.m_arrayField[0] ) + self.assertEqual( 2, tv.m_arrayField[1] ) + self.assertEqual( 3, tv.m_noArrayField ) + self.assertNotEqual( -1, tv.m_arrayField[0] ) + self.assertNotEqual( 0, tv.m_noArrayField ) + try: + tv.m_arrayField[len(tv.m_arrayField)] + self.assertTrue(False) + except IndexError: + self.assertTrue(True) + + def testArrayFieldSlice(self): + tv = target.module.typedVar( "g_struct3" ) + self.assertEqual( [ 0, 2 ], tv.m_arrayField[0:2] ) + + def testArrayFieldSliceNegative(self): + tv = target.module.typedVar( "g_struct3" ) + self.assertEqual( 2, tv.m_arrayField[-1] ) + + def testGlobalVar(self): + self.assertEqual( 4, target.module.typedVar( "g_ulongValue" ) ) + self.assertEqual( 0x80000000, target.module.typedVar( "ulongArray" )[3] ) + self.assertEqual( 0x8000000000000000, target.module.typedVar( "ulonglongArray" )[3] ) + self.assertEqual( -100000, target.module.typedVar( "longArray" )[3]) + self.assertEqual( -10000000000, target.module.typedVar( "longlongArray" )[4]) + self.assertEqual( target.module.g_structTest, target.module.typedVar( "g_structTestPtr" ) ) + + def testContainingRecord(self): + off1 = target.module.type( "structTest" ).fieldOffset("m_field2") + off2 = target.module.offset( "g_structTest" ) + tv = target.module.containingRecord( off2 + off1, "structTest", "m_field2" ) + self.assertEqual( True, tv.m_field2 ) + + def testBitField(self): + tv = target.module.typedVar("g_structWithBits") + self.assertEqual( 4, tv.m_bit0_4 ) + self.assertEqual( 1, tv.m_bit5 ) + self.assertEqual( 5, tv.m_bit6_8 ) + tv = target.module.typedVar("g_structWithSignBits") + self.assertEqual( 4, tv.m_bit0_4 ) + self.assertEqual( -1, tv.m_bit5 ) + self.assertEqual( -3, tv.m_bit6_8 ) + + def testTypedVarList(self): + tvl = target.module.typedVarList( target.module.g_listHead, "listStruct", "listEntry" ) + self.assertEqual( 3, len( tvl ) ) + self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] ) + + tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry" ) + self.assertEqual( 3, len( tvl ) ) + self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] ) + + tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry.Flink" ) + self.assertEqual( 3, len( tvl ) ) + self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] ) + + tvl = target.module.typedVarList( target.module.g_listHead1, "listStruct1", "next" ) + self.assertEqual( 3, len( tvl ) ) + self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] ) + + tvl = pykd.typedVarList( target.module.g_listHead1, target.module.type("listStruct1"), "next" ) + self.assertEqual( 3, len( tvl ) ) + self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] ) + + tvl = pykd.typedVarList( target.module.g_childListHead, target.module.type("ChildEntryTest"), "m_next" ) + self.assertEqual( 3, len( tvl ) ) + self.assertEqual( [1000,2000,3000], [ tv.m_someBaseFiled2 for tv in tvl ] ) + self.assertEqual( [1001,2001,3001], [ tv.m_childFiled1 for tv in tvl ] ) + + tvl1 = target.module.typedVarList( target.module.g_listHead, "listStruct", "listEntry" ) + tvl2 = pykd.typedVarList( target.module.g_listHead, target.moduleName + "!listStruct", "listEntry" ) + self.assertEqual( tvl1, tvl2 ) + + def testTypedVarArray(self): + tvl = target.module.typedVarArray( target.module.g_testArray, "structTest", 2 ) + self.assertEqual( 2, len( tvl ) ) + self.assertEqual( 500, tvl[0].m_field1 ) + self.assertEqual( False, tvl[1].m_field2 ) + + tvl = pykd.typedVarArray( target.module.g_testArray, target.module.type("structTest"), 2 ) + self.assertEqual( 2, len( tvl ) ) + self.assertEqual( 1, tvl[0].m_field3 ) + self.assertEqual( 0, tvl[1].m_field4 ) + + tvl1 = target.module.typedVarArray( target.module.g_testArray, "structTest", 2 ) + tvl2 = pykd.typedVarArray( target.module.g_testArray, target.moduleName + "!structTest", 2 ) + self.assertEqual( tvl1, tvl2 ) + + def testEqual(self): + tv1 = target.module.typedVar("g_structTest") + tv2 = target.module.typedVar("intMatrix") + self.assertEqual( tv1.m_field3, tv2[0][1] ) + + def testEnum(self): + tv = target.module.typedVar("g_classChild") + self.assertEqual( 3, tv.m_enumField ) + self.assertEqual( target.module.type("enumType").THREE, tv.m_enumField ) + + def testIndex(self): + ind = target.module.typedVar( "g_ucharValue" ) + self.assertEqual( 5, [0,5,10][ind] ) + + self.assertTrue( ind in [0,1,2] ) + + tv = target.module.typedVar( "g_struct3" ) + self.assertEqual( 2, tv.m_arrayField[ind] ) + + ind = target.module.typedVar( "g_ulongValue" ) + self.assertEqual( 4, ind ) + self.assertTrue( ind in { 1 : "1", 4 : "2" } ) + self.assertEqual( "2", { 1 : "1", 4 : "2" }[ind] ) + + def testDeref(self): + tv = target.module.typedVar( "g_structTest1" ) + self.assertEqual( target.module.g_structTest, tv.m_field4.deref().getAddress() ) + + tv = target.module.typedVar( "g_structTest" ) + self.assertEqual( 0, tv.m_field4.deref().getAddress() ) + + try: + tv.m_field1.deref() + self.assertTrue(False) + except pykd.BaseException: + pass + + def testSkipDeref(self): + tv = target.module.typedVar( "g_structTest1" ) + self.assertEqual( tv.m_field4.deref().m_field1, tv.m_field4.m_field1 ) + + def testUnNamedStruct(self): + tv = target.module.typedVar( "g_unNamedStruct" ) + self.assertEqual( 4, tv.m_fieldNestedStruct ) + self.assertEqual( 5, tv.m_fieldOfUnNamed ) + + def testPointerToFunction(self): + tv1 = target.module.typedVar( "g_unTypedPtrToFunction" ) + + # if debug: g_unTypedPtrToFunction point to jmp EnumWindowsProc2 (e9 xxxxxxxx) + self.assertTrue( ( target.module.offset("EnumWindowsProc2") == tv1 ) or + ( 0xE9 == pykd.ptrByte( long(tv1) ) ) ) + + tv2 = target.module.typedVar( "g_unTypedPtrToFunction" ) + self.assertEqual( tv1, tv2 ) + + self.assertRaises( pykd.TypeException, tv1.deref ) + self.assertRaises( pykd.TypeException, tv2.deref ) + + def testTypeVarArg(self): + tv1 = target.module.typedVar( "structTest", target.module.g_structTest ) + tv2 = target.module.typedVar( "structTest", tv1 ) + self.assertEqual( tv1, tv2 ) + self.assertTrue( tv1 ) + + def testPrint(self): + self.assertTrue( str(target.module.typedVar( "g_ucharValue" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_ushortValue" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_ulongValue" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_ulonglongValue" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_structWithBits" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_structTest" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_structTest1" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_testArray" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_structTestPtr" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_structTestPtrPtr" ) ) ) + self.assertTrue( str(target.module.typedVar( "longlongArray" ) ) ) + self.assertTrue( str(target.module.typedVar( "intMatrix4" ) ) ) + self.assertTrue( str(target.module.typedVar( "ptrIntMatrix" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_classChild" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_struct3" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_listHead" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_voidPtr" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_arrOfPtrToFunc" ) ) ) + self.assertTrue( str(target.module.typedVar( "g_unTypedPtrToFunction" ) ) ) + + def testNotValidPrint(self): + types = ("structTest", "ULong[100]", "ULong*" ) + for ti in types: + self.assertTrue( str(pykd.typedVar( target.module.type(ti), 0 ) ) ) + + def testStaticField(self): + tv = pykd.typedVar( "g_classChild" ) + self.assertEqual( 200, tv.m_staticField ) + self.assertEqual( 100, tv.m_staticConst ) + + def testAmbiguousFieldAccess(self): + derivedFiledVal = pykd.loadCStr( pykd.typedVar( "g_fieldSameNameStruct" ).m_field ) + self.assertEqual( derivedFiledVal, "toaster" ) + + def testDiamondVirtualInherit(self): + tv = pykd.typedVar( "g_virtChild" ) + self.assertEqual( -100, tv.m_baseField ) + + def testDinkumwareMap(self): + g_map = target.module.typedVar( "g_map" ) + self.assertEqual( 1, g_map._Mysize ) + + def testUdtSubscribe(self): + tv = pykd.typedVar( "g_virtChild" ) + self.assertEqual( 5, len(tv) ) + fieldName, fieldVal = tv[4] + self.assertEqual( fieldName, "m_baseField" ) + self.assertEqual( fieldVal, tv.m_baseField ) + for field in tv: + str( field ) + + def testDeadlockList(self): + lst = [] + entry = pykd.typedVar("entry1").Flink + for i in range( 0, 100000 ): + lst.append(entry) + entry = entry.deref().Flink + + def testWrongArgs(self): + self.assertRaises( pykd.BaseException, pykd.typedVar, None, 0 ) + self.assertRaises( pykd.BaseException, pykd.typedVarList, target.module.g_listHead1, None, "next" ) + self.assertRaises( pykd.BaseException, pykd.typedVarArray, target.module.g_testArray, None, 2 ) + self.assertRaises( pykd.BaseException, pykd.containingRecord, target.module.offset( "g_structTest" ), None, "m_field2" ) diff --git a/test/scripts/typeinfo.py b/test/scripts/typeinfo.py new file mode 100644 index 0000000..67bd6f4 --- /dev/null +++ b/test/scripts/typeinfo.py @@ -0,0 +1,233 @@ +# +# +# + +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() ) + self.assertEqual( "Int4B(*)[2][3]", target.module.type("ptrIntMatrix1").name() ) + + + def testGetField( self ): + """ get field of the complex type """ + ti1 = target.module.type( "structTest" ) + self.assertTrue( hasattr( ti1, "m_field0" ) ) + try: hasattr(ti1, "m_field4" ) # non-exsisting field + except pykd.BaseException: pass + + def testBaseTypes( self ): + + self.assertEqual("Int1B", target.module.type( "Int1B" ).name() ) + self.assertEqual("Int2B", target.module.type( "Int2B" ).name() ) + self.assertEqual("Int4B", target.module.type( "Int4B" ).name() ) + self.assertEqual("Int8B", target.module.type( "Int8B" ).name() ) + self.assertEqual("UInt1B", target.module.type( "UInt1B" ).name() ) + self.assertEqual("UInt2B", target.module.type( "UInt2B" ).name() ) + self.assertEqual("UInt4B", target.module.type( "UInt4B" ).name() ) + self.assertEqual("UInt8B", target.module.type( "UInt8B" ).name() ) + + self.assertEqual("Long", target.module.type( "Long" ).name() ) + self.assertEqual("ULong", target.module.type( "ULong" ).name() ) + self.assertEqual("Bool", target.module.type( "Bool" ).name() ) + self.assertEqual("Char", target.module.type("Char").name() ) + self.assertEqual("WChar", target.module.type("WChar").name() ) + + self.assertEqual( 1, target.module.type("Int1B").size() ) + self.assertEqual( 1, target.module.type("UInt1B").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() ) + + self.assertEqual( 4, target.module.type("Long" ).size() ) + self.assertEqual( 4, target.module.type("ULong" ).size() ) + self.assertEqual( 1, target.module.type("Bool" ).size() ) + self.assertEqual( 1, target.module.type("Char").size() ) + self.assertEqual( 2, target.module.type("WChar").size() ) + + try: + self.assertEqual("Int9B", target.module.type( "Int9B" ).name() ) + except pykd.SymbolException: + pass + + def testBaseTypePtr(self): + self.assertEqual("Int1B*", target.module.type( "Int1B*" ).name() ) + self.assertEqual("Int1B", target.module.type( "Int1B*" ).deref().name() ) + + def testBaseTypeArray(self): + self.assertEqual("Int4B[20]", target.module.type( "Int4B[20]" ).name() ) + + 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") ) + + ti2 = target.module.type( "struct2" ) + self.assertTrue( ti2.fieldOffset("m_union") >= ti2.m_struct.size() ) + self.assertEqual( 0, ti2.m_union.fieldOffset("m_value") ) + + 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() ) + self.assertEqual( pykd.sizeof("Int1B"), target.module.type("Int1B").size() ) + + 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() ) + self.assertEqual( "ULong:3", ti.m_bit6_8.name() ) + 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): + self.assertEqual( "listStruct1*", target.module.type( "g_listHead1" ).name() ) + self.assertEqual( "listStruct1*[2]", target.module.type( "g_arrOfListStruct1" ).name()) + self.assertEqual( "Void*", target.module.type( "g_voidPtr" ).name() ) + self.assertEqual( "Void*[3]", target.module.type( "g_arrOfVoidPtr" ).name()) + self.assertEqual( "*", target.module.type( "g_ptrToFunction" ).name()) + self.assertEqual( "*[4]", target.module.type( "g_arrOfPtrToFunc" ).name()) + + def testUnion(self): + ti = target.module.type("unionTest") + self.assertEqual( 0, ti.fieldOffset("m_doubleValue") ) + self.assertEqual( 0, ti.fieldOffset("m_bits") ) + self.assertEqual( ti.size(), ti.m_doubleValue.size() ) + + def testAsMap(self): + ti = target.module.type("enumType") + self.assertEqual( { 1 : "ONE", 2 : "TWO", 3 : "THREE" }, ti.asMap() ) + + def testDeref(self): + ti = target.module.type("listStruct1") + self.assertEqual( "listStruct1", ti.next.deref().name() ) + + ti = target.module.type("listStruct1*") + self.assertEqual( "listStruct1", ti.deref().name() ) + + ti = target.module.type("classChild") + self.assertRaises( pykd.BaseException, ti.deref ); + + def testNestedStruct( self ): + ti = target.module.type("StructWithNested") + self.assertTrue( hasattr( ti, "m_field" ) ) + self.assertTrue( hasattr( ti, "m_field2" ) ) + self.assertFalse( hasattr( ti, "m_nestedFiled" ) ) + + ti = target.module.type("StructWithNested::Nested") + self.assertTrue( hasattr( ti, "m_nestedFiled" ) ) + + def testPrint(self): + self.assertTrue( str(target.module.type( "g_ucharValue" ) ) ) + self.assertTrue( str(target.module.type( "g_ushortValue" ) ) ) + self.assertTrue( str(target.module.type( "g_ulongValue" ) ) ) + self.assertTrue( str(target.module.type( "g_ulonglongValue" ) ) ) + 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" ) ) ) + self.assertTrue( str(target.module.type( "g_struct3" ) ) ) + 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" ) ) ) + + 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" ) ) + + def testUdtSubscribe(self): + ti = pykd.typeInfo( "g_virtChild" ) + self.assertEqual( 5, len(ti) ) + for field in ti: + str( field ) + + def testStructNullSize(self): + ti = target.module.type("structNullSize") + self.assertEqual( 0, len(ti) ) + + def testDerefName(self): + entry = pykd.typedVar("entry1").Flink + self.assertEqual( "_LIST_ENTRY*", entry.type().name() ) + + def testPtrTo(self): + ti = pykd.typeInfo("UInt8B").ptrTo() + self.assertTrue( "UInt8B*", ti.name() ) + self.assertNotEqual( 0, ti.size() ) + + def testArrayOf(self): + ti = pykd.typeInfo("UInt8B").arrayOf(10) + self.assertTrue( "UInt8B[10]", ti.name() ) +