[0.2.x] updated: getting local vars by index

git-svn-id: https://pykd.svn.codeplex.com/svn@82027 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2012-12-25 07:15:09 +00:00 committed by Mikhail I. Izmestev
parent 4021a60d2d
commit a718ec6716
5 changed files with 201 additions and 11 deletions

View File

@ -69,8 +69,8 @@ struct STACK_FRAME_DESC {
ULONG64 stackOffset; ULONG64 stackOffset;
}; };
void getCurrentFrame(STACK_FRAME_DESC &frame );
void getStackTrace(std::vector<STACK_FRAME_DESC> &frames); void getStackTrace(std::vector<STACK_FRAME_DESC> &frames);
void getStackTraceWow64(std::vector<STACK_FRAME_DESC> &frames); void getStackTraceWow64(std::vector<STACK_FRAME_DESC> &frames);
// callback events // callback events

View File

@ -347,6 +347,167 @@ ULONG StackFrame::getParamCount()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
python::object StackFrame::getLocalByIndex( ULONG index )
{
ModulePtr mod = Module::loadModuleByOffset( m_instructionOffset);
LONG displacemnt;
SymbolPtr func = mod->getSymbolByVa( m_instructionOffset, SymTagFunction, &displacemnt );
#ifdef _DEBUG
std::string funcName;
funcName = func->getName();
#endif // _DEBUG
if (!IsInDebugRange(func, static_cast<ULONG>( m_instructionOffset - mod->getBase())))
{
throw DbgException("is not debug range");
}
// find var in current scope
SymbolPtrList symList = func->findChildren(SymTagData);
SymbolPtrList::iterator itVar = symList.begin();
SymbolPtr symVar;
ULONG i = 0;
for (; itVar != symList.end(); ++itVar, ++i)
{
if ( i == index )
{
symVar = *itVar;
break;
}
}
if ( itVar == symList.end() )
{
// find inners scopes
SymbolPtrList scopeList = func->findChildren(SymTagBlock);
SymbolPtrList::iterator itScope = scopeList.begin();
ULONG ipRva = static_cast<ULONG>( m_instructionOffset - mod->getBase());
for (; itScope != scopeList.end() && !symVar; ++itScope)
{
SymbolPtr scope = *itScope;
ULONG scopeRva = scope->getRva();
if (scopeRva <= ipRva && (scopeRva + scope->getSize()) > ipRva)
{
SymbolPtrList symList = scope->findChildren(SymTagData);
SymbolPtrList::iterator itVar = symList.begin();
for (; itVar != symList.end(); ++itVar, ++i)
{
if ( i == index )
{
symVar = *itVar;
break;
}
}
}
}
}
if ( !symVar )
throw DbgException("local var not found");
ULONG64 varAddr;
const LocationType locType = static_cast<LocationType>(symVar->getLocType());
switch (locType)
{
case LocIsStatic:
varAddr = mod->getBase() + symVar->getRva();
break;
case LocIsRegRel:
{
RegRealativeId rri;
rri = static_cast<RegRealativeId>(symVar->getRegRealativeId());
varAddr = getValue(rri, symVar->getOffset());
}
break;
default:
BOOST_ASSERT(LocIsEnregistered == locType);
throw DbgException("");
}
TypeInfoPtr typeInfo = TypeInfo::getTypeInfo(symVar);
TypedVarPtr typedVar = TypedVar::getTypedVarByTypeInfo(typeInfo, varAddr);
typedVar->setDataKind( symVar->getDataKind() );
return python::object( typedVar );
}
////////////////////////////////////////////////////////////////////////////////
python::object StackFrame::getParamByIndex( ULONG index )
{
ModulePtr mod = Module::loadModuleByOffset( m_instructionOffset);
LONG displacemnt;
SymbolPtr func = mod->getSymbolByVa( m_instructionOffset, SymTagFunction, &displacemnt );
#ifdef _DEBUG
std::string funcName;
funcName = func->getName();
#endif // _DEBUG
if (!IsInDebugRange(func, static_cast<ULONG>( m_instructionOffset - mod->getBase())))
{
throw DbgException("is not debug range");
}
// find var in current scope
SymbolPtrList symList = func->findChildren(SymTagData);
SymbolPtrList::iterator itVar = symList.begin();
SymbolPtr symVar;
for ( ULONG i = 0; itVar != symList.end(); ++itVar )
{
if ( (*itVar)->getDataKind() == DataIsParam )
{
if ( i == index )
{
symVar = *itVar;
break;
}
i++;
}
}
if ( !symVar )
throw DbgException("local var not found");
ULONG64 varAddr;
const LocationType locType = static_cast<LocationType>(symVar->getLocType());
switch (locType)
{
case LocIsStatic:
varAddr = mod->getBase() + symVar->getRva();
break;
case LocIsRegRel:
{
RegRealativeId rri;
rri = static_cast<RegRealativeId>(symVar->getRegRealativeId());
varAddr = getValue(rri, symVar->getOffset());
}
break;
default:
BOOST_ASSERT(LocIsEnregistered == locType);
throw DbgException("");
}
TypeInfoPtr typeInfo = TypeInfo::getTypeInfo(symVar);
TypedVarPtr typedVar = TypedVar::getTypedVarByTypeInfo(typeInfo, varAddr);
typedVar->setDataKind( symVar->getDataKind() );
return python::object( typedVar );
}
////////////////////////////////////////////////////////////////////////////////
python::list getCurrentStack() python::list getCurrentStack()
{ {
std::vector<STACK_FRAME_DESC> frames; std::vector<STACK_FRAME_DESC> frames;
@ -385,9 +546,9 @@ python::list getCurrentStackWow64()
StackFramePtr getCurrentStackFrame() StackFramePtr getCurrentStackFrame()
{ {
std::vector<STACK_FRAME_DESC> frames; STACK_FRAME_DESC frame;
getStackTrace( frames ); getCurrentFrame( frame );
return StackFramePtr( new StackFrame( frames[0] ) ); return StackFramePtr( new StackFrame( frame ) );
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -46,13 +46,9 @@ public:
python::object getParamByName( const std::string& name ); python::object getParamByName( const std::string& name );
python::object getLocalByIndex( ULONG index ){ python::object getLocalByIndex( ULONG index );
return python::long_(0);
}
python::object getParamByIndex( ULONG index ){ python::object getParamByIndex( ULONG index );
return python::long_(0);
}
public: public:
@ -126,7 +122,7 @@ private:
} }
python::object getVarByIndex(ULONG index) const { python::object getVarByIndex(ULONG index) const {
return python::long_(0L); return m_frame->getParamByIndex(index);
} }
}; };

View File

@ -863,6 +863,33 @@ static void buildStacksFrames(
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void getCurrentFrame(STACK_FRAME_DESC &frame )
{
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
HRESULT hres;
frame.number = 0;
hres = g_dbgEng->registers->GetInstructionOffset2( DEBUG_REGSRC_FRAME, &frame.instructionOffset );
if ( FAILED(hres) )
throw DbgException( "IDebugRegisters2::GetInstructionOffset2", hres );
hres = g_dbgEng->control->GetReturnOffset( &frame.returnOffset );
if ( FAILED(hres) )
throw DbgException( "IDebugControl::GetReturnOffset", hres );
hres = g_dbgEng->registers->GetFrameOffset2( DEBUG_REGSRC_FRAME, &frame.frameOffset );
if ( FAILED(hres) )
throw DbgException( "IDebugRegisters2::GetFrameOffset2", hres );
hres = g_dbgEng->registers->GetStackOffset2( DEBUG_REGSRC_FRAME, &frame.stackOffset );
if ( FAILED(hres) )
throw DbgException( "IDebugRegisters2::GetStackOffset2", hres );
}
///////////////////////////////////////////////////////////////////////////////
void getStackTrace(std::vector<STACK_FRAME_DESC> &frames) void getStackTrace(std::vector<STACK_FRAME_DESC> &frames)
{ {
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );

View File

@ -23,6 +23,7 @@ def testEnumWindowsProc1Locals(testCase, locals):
testCase.assertEqual( DataIsStaticLocal, locals["staticVar"].dataKind() ) testCase.assertEqual( DataIsStaticLocal, locals["staticVar"].dataKind() )
testCase.assertEqual( locals["dwProccessId"] + 1, locals["staticVar"] ) testCase.assertEqual( locals["dwProccessId"] + 1, locals["staticVar"] )
class LocalVarsTest(unittest.TestCase): class LocalVarsTest(unittest.TestCase):
def testLocalVariable(self): def testLocalVariable(self):
@ -41,3 +42,8 @@ class LocalVarsTest(unittest.TestCase):
locals = pykd.getLocals() locals = pykd.getLocals()
self.assertEqual( len(locals), 2 ) self.assertEqual( len(locals), 2 )
self.assertTrue( locals[0] == 7 or locals[1] == 7 ) 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 )