mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-29 11:53:23 +08:00
[0.1.x] added : typedVarList, typedVarArray, containingRecord for global space
git-svn-id: https://pykd.svn.codeplex.com/svn@75077 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
2d1d141a4c
commit
064f28eda0
@ -439,38 +439,68 @@ void terminateProcess()
|
||||
|
||||
static const boost::regex moduleSymMatch("^(?:([^!]*)!)?([^!]+)$");
|
||||
|
||||
TypedVarPtr DebugClient::getTypedVarByName( const std::string &varName )
|
||||
void DebugClient::splitSymName( const std::string &fullName, std::string &moduleName, std::string &symbolName )
|
||||
{
|
||||
boost::cmatch matchResult;
|
||||
|
||||
if ( !boost::regex_match( varName.c_str(), matchResult, moduleSymMatch ) )
|
||||
if ( !boost::regex_match( fullName.c_str(), matchResult, moduleSymMatch ) )
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << "invalid symbol name: " << varName;
|
||||
sstr << "invalid symbol name: " << fullName;
|
||||
throw SymbolException( sstr.str() );
|
||||
}
|
||||
|
||||
std::string symName = std::string( matchResult[2].first, matchResult[2].second );
|
||||
symbolName = std::string( matchResult[2].first, matchResult[2].second );
|
||||
|
||||
if ( matchResult[1].matched )
|
||||
{
|
||||
Module module = loadModuleByName( std::string( matchResult[1].first, matchResult[1].second ) );
|
||||
moduleName = std::string( matchResult[1].first, matchResult[1].second );
|
||||
|
||||
return module.getTypedVarByName( symName );
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT hres;
|
||||
ULONG64 base;
|
||||
|
||||
hres = m_symbols->GetSymbolModule( ( std::string("!") + symName ).c_str(), &base );
|
||||
hres = m_symbols->GetSymbolModule( ( std::string("!") + symbolName ).c_str(), &base );
|
||||
if ( FAILED( hres ) )
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << "failed to find module for symbol: " << symName;
|
||||
sstr << "failed to find module for symbol: " << symbolName;
|
||||
throw SymbolException( sstr.str() );
|
||||
}
|
||||
|
||||
Module module = loadModuleByOffset( base );
|
||||
char nameBuffer[0x100];
|
||||
|
||||
hres =
|
||||
m_symbols->GetModuleNameString(
|
||||
DEBUG_MODNAME_MODULE,
|
||||
DEBUG_ANY_ID,
|
||||
base,
|
||||
nameBuffer,
|
||||
sizeof(nameBuffer),
|
||||
NULL );
|
||||
|
||||
if ( FAILED( hres ) )
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << "failed to find module for symbol: " << symbolName;
|
||||
throw SymbolException( sstr.str() );
|
||||
}
|
||||
|
||||
moduleName = std::string( nameBuffer );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypedVarPtr DebugClient::getTypedVarByName( const std::string &varName )
|
||||
{
|
||||
std::string moduleName;
|
||||
std::string symName;
|
||||
|
||||
splitSymName( varName, moduleName, symName );
|
||||
|
||||
Module module = loadModuleByName( moduleName );
|
||||
|
||||
return module.getTypedVarByName( symName );
|
||||
}
|
||||
@ -479,39 +509,143 @@ TypedVarPtr DebugClient::getTypedVarByName( const std::string &varName )
|
||||
|
||||
TypedVarPtr DebugClient::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr )
|
||||
{
|
||||
boost::cmatch matchResult;
|
||||
addr = addr64( addr );
|
||||
|
||||
if ( !boost::regex_match( typeName.c_str(), matchResult, moduleSymMatch ) )
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << "invalid symbol name: " << typeName;
|
||||
throw SymbolException( sstr.str() );
|
||||
}
|
||||
std::string moduleName;
|
||||
std::string symName;
|
||||
|
||||
std::string symName = std::string( matchResult[2].first, matchResult[2].second );
|
||||
splitSymName( typeName, moduleName, symName );
|
||||
|
||||
if ( matchResult[1].matched )
|
||||
{
|
||||
Module module = loadModuleByName( std::string( matchResult[1].first, matchResult[1].second ) );
|
||||
|
||||
return module.getTypedVarByTypeName( symName, addr );
|
||||
}
|
||||
|
||||
HRESULT hres;
|
||||
ULONG64 base;
|
||||
|
||||
hres = m_symbols->GetSymbolModule( ( std::string("!") + symName ).c_str(), &base );
|
||||
if ( FAILED( hres ) )
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << "failed to find module for symbol: " << symName;
|
||||
throw SymbolException( sstr.str() );
|
||||
}
|
||||
|
||||
Module module = loadModuleByOffset( base );
|
||||
Module module = loadModuleByName( moduleName );
|
||||
|
||||
return module.getTypedVarByTypeName( symName, addr );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypedVarPtr DebugClient::containingRecordByName( ULONG64 addr, const std::string &typeName, const std::string &fieldName )
|
||||
{
|
||||
addr = addr64( addr );
|
||||
|
||||
std::string moduleName;
|
||||
std::string symName;
|
||||
|
||||
splitSymName( typeName, moduleName, symName );
|
||||
|
||||
Module module = loadModuleByName( moduleName );
|
||||
|
||||
return module.containingRecordByName( addr, symName, fieldName );
|
||||
}
|
||||
|
||||
TypedVarPtr containingRecordByName( ULONG64 addr, const std::string &typeName, const std::string &fieldName )
|
||||
{
|
||||
return g_dbgClient->containingRecordByName( addr, typeName, fieldName );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypedVarPtr DebugClient::containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName )
|
||||
{
|
||||
addr = addr64(addr);
|
||||
|
||||
TypeInfoPtr fieldTypeInfo = typeInfo->getField( fieldName );
|
||||
|
||||
VarDataPtr varData = VarDataMemory::factory( m_dataSpaces, addr - fieldTypeInfo->getOffset() );
|
||||
|
||||
return TypedVar::getTypedVar( m_client, typeInfo, varData );
|
||||
}
|
||||
|
||||
TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName )
|
||||
{
|
||||
return g_dbgClient->containingRecordByType( addr, typeInfo, fieldName );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
python::list DebugClient::getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &typeInfo, const std::string &listEntryName )\
|
||||
{
|
||||
python::list lst;
|
||||
|
||||
listHeadAddress = addr64( listHeadAddress );
|
||||
|
||||
ULONG64 entryAddress = 0;
|
||||
|
||||
TypeInfoPtr fieldTypeInfo = typeInfo->getField( listEntryName );
|
||||
|
||||
if ( fieldTypeInfo->getName() == ( typeInfo->getName() + "*" ) )
|
||||
{
|
||||
for( entryAddress = ptrPtr( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress + fieldTypeInfo->getOffset() ) )
|
||||
lst.append( getTypedVarByTypeInfo( typeInfo, entryAddress ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( entryAddress = ptrPtr( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress ) )
|
||||
lst.append( containingRecordByType( entryAddress, typeInfo, listEntryName ) );
|
||||
}
|
||||
|
||||
return lst;
|
||||
}
|
||||
|
||||
python::list getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &typeInfo, const std::string &listEntryName )
|
||||
{
|
||||
return g_dbgClient->getTypedVarListByType( listHeadAddress, typeInfo, listEntryName );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
python::list DebugClient::getTypedVarListByTypeName( ULONG64 listHeadAddress, const std::string &typeName, const std::string &listEntryName )
|
||||
{
|
||||
std::string moduleName;
|
||||
std::string symName;
|
||||
|
||||
splitSymName( typeName, moduleName, symName );
|
||||
|
||||
Module module = loadModuleByName( moduleName );
|
||||
|
||||
return module.getTypedVarListByTypeName( listHeadAddress, symName, listEntryName );
|
||||
}
|
||||
|
||||
python::list getTypedVarListByTypeName( ULONG64 listHeadAddress, const std::string &typeName, const std::string &listEntryName )
|
||||
{
|
||||
return g_dbgClient->getTypedVarListByTypeName( listHeadAddress, typeName, listEntryName );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
python::list DebugClient::getTypedVarArrayByType( ULONG64 address, const TypeInfoPtr &typeInfo, ULONG number )
|
||||
{
|
||||
address = addr64(address);
|
||||
|
||||
python::list lst;
|
||||
|
||||
for( ULONG i = 0; i < number; ++i )
|
||||
lst.append( getTypedVarByTypeInfo( typeInfo, address + i * typeInfo->getSize() ) );
|
||||
|
||||
return lst;
|
||||
}
|
||||
|
||||
python::list getTypedVarArrayByType( ULONG64 address, const TypeInfoPtr &typeInfo, ULONG number )
|
||||
{
|
||||
return g_dbgClient->getTypedVarArrayByType( address, typeInfo, number );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
python::list DebugClient::getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number )
|
||||
{
|
||||
std::string moduleName;
|
||||
std::string symName;
|
||||
|
||||
splitSymName( typeName, moduleName, symName );
|
||||
|
||||
Module module = loadModuleByName( moduleName );
|
||||
|
||||
return module.getTypedVarArrayByTypeName( addr, symName, number );
|
||||
}
|
||||
|
||||
python::list getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number )
|
||||
{
|
||||
return g_dbgClient->getTypedVarArrayByTypeName( addr, typeName, number );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -325,6 +325,8 @@ public:
|
||||
void removeBp(BPOINT_ID Id);
|
||||
void removeAllBp();
|
||||
|
||||
void splitSymName( const std::string &fullName, std::string &moduleName, std::string &symbolName );
|
||||
|
||||
TypedVarPtr getTypedVarByName( const std::string &varName );
|
||||
|
||||
TypedVarPtr getTypedVarByTypeName( const std::string &typeName, ULONG64 addr );
|
||||
@ -332,7 +334,21 @@ public:
|
||||
TypedVarPtr getTypedVarByTypeInfo( const TypeInfoPtr &typeInfo, ULONG64 addr ) {
|
||||
return TypedVar::getTypedVar( m_client, typeInfo, VarDataMemory::factory(m_dataSpaces, addr) );
|
||||
}
|
||||
|
||||
|
||||
TypedVarPtr containingRecordByName( ULONG64 addr, const std::string &typeName, const std::string &fieldName );
|
||||
|
||||
TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName );
|
||||
|
||||
|
||||
python::list getTypedVarListByTypeName( ULONG64 listHeadAddres, const std::string &typeName, const std::string &listEntryName );
|
||||
|
||||
python::list getTypedVarListByType( ULONG64 listHeadAddres, const TypeInfoPtr &typeInfo, const std::string &listEntryName );
|
||||
|
||||
python::list getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number );
|
||||
|
||||
python::list getTypedVarArrayByType( ULONG64 addr, const TypeInfoPtr &typeInfo, ULONG number );
|
||||
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
python::list
|
||||
@ -388,6 +404,18 @@ void terminateProcess();
|
||||
|
||||
void waitForEvent();
|
||||
|
||||
TypedVarPtr containingRecordByName( ULONG64 addr, const std::string &typeName, const std::string &fieldName );
|
||||
|
||||
TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName );
|
||||
|
||||
python::list getTypedVarListByTypeName( ULONG64 listHeadAddres, const std::string &typeName, const std::string &listEntryName );
|
||||
|
||||
python::list getTypedVarListByType( ULONG64 listHeadAddres, const TypeInfoPtr &typeInfo, const std::string &listEntryName );
|
||||
|
||||
python::list getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number );
|
||||
|
||||
python::list getTypedVarArrayByType( ULONG64 addr, const TypeInfoPtr &typeInfo, ULONG number );
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Synthetic symbols global finctions:
|
||||
|
||||
|
@ -304,6 +304,20 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Return symbol path" )
|
||||
.def( "trace", &DebugClient::changeDebuggerStatus<DEBUG_STATUS_STEP_INTO>,
|
||||
"Change debugger status to DEBUG_STATUS_STEP_INTO" )
|
||||
.def("typedVarList", &DebugClient::getTypedVarListByTypeName,
|
||||
"Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" )
|
||||
.def("typedVarList", &DebugClient::getTypedVarListByType,
|
||||
"Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" )
|
||||
.def("typedVarArray", &DebugClient::getTypedVarArrayByTypeName,
|
||||
"Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" )
|
||||
.def("typedVarArray", &DebugClient::getTypedVarArrayByType,
|
||||
"Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" )
|
||||
.def("containingRecord", &DebugClient::containingRecordByName,
|
||||
"Return instance of the typedVar class. It's value are loaded from the target memory."
|
||||
"The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" )
|
||||
.def("containingRecord", &DebugClient::containingRecordByType,
|
||||
"Return instance of the typedVar class. It's value are loaded from the target memory."
|
||||
"The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" )
|
||||
.def( "waitForEvent", &DebugClient::waitForEvent,
|
||||
"Wait for events that breaks into the debugger" )
|
||||
.def( "wrmsr", &DebugClient::setMSR,
|
||||
@ -491,6 +505,20 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Set MSR value" );
|
||||
python::def( "trace", &changeDebuggerStatus<DEBUG_STATUS_STEP_INTO>,
|
||||
"Change debugger status to DEBUG_STATUS_STEP_INTO" );
|
||||
python::def("typedVarList", &getTypedVarListByTypeName,
|
||||
"Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" );
|
||||
python::def("typedVarList", &getTypedVarListByType,
|
||||
"Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" );
|
||||
python::def("typedVarArray", &getTypedVarArrayByTypeName,
|
||||
"Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" );
|
||||
python::def("typedVarArray", &getTypedVarArrayByType,
|
||||
"Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" );
|
||||
python::def("containingRecord", &containingRecordByName,
|
||||
"Return instance of the typedVar class. It's value are loaded from the target memory."
|
||||
"The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" );
|
||||
python::def("containingRecord", &containingRecordByType,
|
||||
"Return instance of the typedVar class. It's value are loaded from the target memory."
|
||||
"The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" );
|
||||
python::def( "waitForEvent", &waitForEvent,
|
||||
"Wait for events that breaks into the debugger" );
|
||||
python::def( "getNumberProcessors", &getNumberProcessors,
|
||||
|
@ -347,12 +347,12 @@ python::list Module::getTypedVarListByType( ULONG64 listHeadAddress, const TypeI
|
||||
|
||||
if ( fieldTypeInfo->getName() == ( typeInfo->getName() + "*" ) )
|
||||
{
|
||||
for( entryAddress = ptrPtr( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress + fieldTypeInfo->getOffset() ) )
|
||||
for( entryAddress = ptrPtr( listHeadAddress, m_dataSpaces ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress + fieldTypeInfo->getOffset() ) )
|
||||
lst.append( getTypedVarByType( typeInfo, entryAddress ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( entryAddress = ptrPtr( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress ) )
|
||||
for( entryAddress = ptrPtr( listHeadAddress, m_dataSpaces ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress ) )
|
||||
lst.append( containingRecordByType( entryAddress, typeInfo, listEntryName ) );
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ class BaseTest( unittest.TestCase ):
|
||||
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') )
|
||||
@ -76,6 +77,8 @@ class BaseTest( unittest.TestCase ):
|
||||
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') )
|
||||
|
||||
@ -95,7 +98,6 @@ class BaseTest( unittest.TestCase ):
|
||||
|
||||
def testOldRemovedApi( self ):
|
||||
""" Branch test: old API 0.0.x what should be removed """
|
||||
self.assertFalse( hasattr(pykd, 'containingRecord') )
|
||||
self.assertFalse( hasattr(pykd, 'dbgModuleClass') )
|
||||
self.assertFalse( hasattr(pykd, 'dbgStackFrameClass') )
|
||||
self.assertFalse( hasattr(pykd, 'debugEvent') )
|
||||
@ -104,8 +106,6 @@ class BaseTest( unittest.TestCase ):
|
||||
self.assertFalse( hasattr(pykd, 'loadPtrs') )
|
||||
self.assertFalse( hasattr(pykd, 'reloadModule') )
|
||||
self.assertFalse( hasattr(pykd, 'sizeof') )
|
||||
self.assertFalse( hasattr(pykd, 'typedVarArray') )
|
||||
self.assertFalse( hasattr(pykd, 'typedVarList') )
|
||||
self.assertFalse( hasattr(pykd, 'windbgIn') )
|
||||
self.assertFalse( hasattr(pykd, 'windbgOut') )
|
||||
self.assertFalse( hasattr(pykd, 'bp') )
|
||||
|
@ -125,6 +125,11 @@ class TypedVarTest( unittest.TestCase ):
|
||||
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 )
|
||||
@ -137,6 +142,10 @@ class TypedVarTest( unittest.TestCase ):
|
||||
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")
|
||||
|
Loading…
Reference in New Issue
Block a user