mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[0.2.x] updated : working with local vars
git-svn-id: https://pykd.svn.codeplex.com/svn@81665 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
6dc5ac2f20
commit
a1a69b9826
@ -1,209 +0,0 @@
|
||||
|
||||
#include <stdafx.h>
|
||||
|
||||
#include "localvar.h"
|
||||
#include "module.h"
|
||||
#include "symengine.h"
|
||||
#include "dbgengine.h"
|
||||
#include "typedvar.h"
|
||||
|
||||
namespace pykd {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
python::dict getLocals()
|
||||
{
|
||||
return getLocalsByFrame( getCurrentStackFrame() );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class BuildLocals
|
||||
{
|
||||
public:
|
||||
BuildLocals( ModulePtr mod, const StackFrame &frame )
|
||||
: m_mod(mod), m_frame(frame), m_formalGen(0)
|
||||
{
|
||||
m_ipRva = static_cast<ULONG>(m_frame.m_instructionOffset - m_mod->getBase());
|
||||
}
|
||||
|
||||
void process( SymbolPtr symParent );
|
||||
|
||||
python::dict &getResult() {
|
||||
return m_dct;
|
||||
}
|
||||
|
||||
protected:
|
||||
void addVar(SymbolPtr symVar);
|
||||
|
||||
private:
|
||||
ModulePtr m_mod;
|
||||
const StackFrame &m_frame;
|
||||
python::dict m_dct;
|
||||
size_t m_formalGen;
|
||||
ULONG m_ipRva;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void BuildLocals::process(
|
||||
SymbolPtr symParent
|
||||
)
|
||||
{
|
||||
// add vars from current scope
|
||||
SymbolPtrList symList = symParent->findChildren(SymTagData);
|
||||
SymbolPtrList::iterator itVar = symList.begin();
|
||||
for (; itVar != symList.end(); ++itVar)
|
||||
addVar(*itVar);
|
||||
|
||||
// find inners scopes
|
||||
symList = symParent->findChildren(SymTagBlock);
|
||||
SymbolPtrList::iterator itScope = symList.begin();
|
||||
for (; itScope != symList.end(); ++itScope)
|
||||
{
|
||||
SymbolPtr scope = *itScope;
|
||||
ULONG scopeRva = scope->getRva();
|
||||
if (scopeRva <= m_ipRva && (scopeRva + scope->getSize()) > m_ipRva)
|
||||
process(scope);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void BuildLocals::addVar(SymbolPtr symVar)
|
||||
{
|
||||
std::string name;
|
||||
try
|
||||
{
|
||||
name = symVar->getName();
|
||||
if (name.empty())
|
||||
return;
|
||||
}
|
||||
catch (const SymbolException &except)
|
||||
{
|
||||
DBG_UNREFERENCED_PARAMETER(except);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_dct.has_key(name))
|
||||
{
|
||||
std::stringstream sstream;
|
||||
sstream << name << "#" << std::dec << ++m_formalGen;
|
||||
name = sstream.str();
|
||||
}
|
||||
|
||||
BOOST_ASSERT(!m_dct.has_key(name));
|
||||
if (m_dct.has_key(name))
|
||||
return;
|
||||
|
||||
ULONG64 varAddr;
|
||||
const LocationType locType = static_cast<LocationType>(symVar->getLocType());
|
||||
switch (locType)
|
||||
{
|
||||
case LocIsStatic:
|
||||
varAddr = m_mod->getBase() + symVar->getRva();
|
||||
break;
|
||||
|
||||
case LocIsRegRel:
|
||||
{
|
||||
RegRealativeId rri;
|
||||
try
|
||||
{
|
||||
rri = static_cast<RegRealativeId>(symVar->getRegRealativeId());
|
||||
}
|
||||
catch (const DbgException &except)
|
||||
{
|
||||
DBG_UNREFERENCED_PARAMETER(except);
|
||||
return;
|
||||
}
|
||||
varAddr = m_frame.getValue(rri, symVar->getOffset());
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
BOOST_ASSERT(LocIsEnregistered == locType);
|
||||
return;
|
||||
}
|
||||
|
||||
TypeInfoPtr typeInfo = TypeInfo::getTypeInfo(symVar);
|
||||
TypedVarPtr typedVar = TypedVar::getTypedVarByTypeInfo(typeInfo, varAddr);
|
||||
typedVar->setDataKind( symVar->getDataKind() );
|
||||
m_dct[name] = typedVar;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool IsInDebugRange(
|
||||
SymbolPtr func,
|
||||
ULONG ipRva
|
||||
)
|
||||
{
|
||||
SymbolPtrList lstFuncDebugStart;
|
||||
SymbolPtrList lstFuncDebugEnd;
|
||||
|
||||
try
|
||||
{
|
||||
lstFuncDebugStart = func->findChildren(SymTagFuncDebugStart);
|
||||
if (1 != lstFuncDebugStart.size())
|
||||
{
|
||||
BOOST_ASSERT(lstFuncDebugStart.empty());
|
||||
return true;
|
||||
}
|
||||
|
||||
lstFuncDebugEnd = func->findChildren(SymTagFuncDebugEnd);
|
||||
if (1 != lstFuncDebugEnd.size())
|
||||
{
|
||||
BOOST_ASSERT(lstFuncDebugEnd.empty());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (const SymbolException &except)
|
||||
{
|
||||
DBG_UNREFERENCED_PARAMETER(except);
|
||||
return true;
|
||||
}
|
||||
|
||||
return
|
||||
((*lstFuncDebugStart.begin())->getRva() <= ipRva) &&
|
||||
((*lstFuncDebugEnd.begin())->getRva() >= ipRva);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
python::dict getLocalsByFrame( const StackFrame &frame )
|
||||
{
|
||||
// query target fuction by $ip register
|
||||
ModulePtr mod;
|
||||
SymbolPtr func;
|
||||
try
|
||||
{
|
||||
mod = Module::loadModuleByOffset(frame.m_instructionOffset);
|
||||
LONG displacemnt;
|
||||
func = mod->getSymbolByVa(frame.m_instructionOffset, SymTagFunction, &displacemnt );
|
||||
}
|
||||
catch (const DbgException &except)
|
||||
{
|
||||
DBG_UNREFERENCED_PARAMETER(except);
|
||||
return python::dict();
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
std::string funcName;
|
||||
funcName = func->getName();
|
||||
#endif // _DEBUG
|
||||
|
||||
if (!IsInDebugRange(func, static_cast<ULONG>(frame.m_instructionOffset - mod->getBase())))
|
||||
{
|
||||
// not in debug range
|
||||
return python::dict();
|
||||
}
|
||||
|
||||
BuildLocals buildLocals(mod, frame);
|
||||
buildLocals.process(func);
|
||||
return buildLocals.getResult();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} //end pykd namespace
|
||||
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "stkframe.h"
|
||||
|
||||
namespace pykd {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
python::dict getLocals();
|
||||
|
||||
python::dict getLocalsByFrame( const StackFrame &frame );
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // end pykd namespace
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Version="9,00"
|
||||
Name="pykd"
|
||||
ProjectGUID="{FE961905-666F-4908-A212-961465F46F13}"
|
||||
RootNamespace="pykd"
|
||||
@ -389,10 +389,6 @@
|
||||
RelativePath=".\eventhandler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\localvar.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\module.cpp"
|
||||
>
|
||||
@ -507,10 +503,6 @@
|
||||
RelativePath=".\eventhandler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\localvar.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\module.h"
|
||||
>
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "cpureg.h"
|
||||
#include "disasm.h"
|
||||
#include "stkframe.h"
|
||||
#include "localvar.h"
|
||||
#include "bpoint.h"
|
||||
|
||||
#include "win/dbgio.h"
|
||||
@ -245,9 +244,14 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Set current processor mode by string (X86, ARM, IA64 or X64)" );
|
||||
|
||||
// stack and local variables
|
||||
python::def( "getCurrentStack", &getCurrentStack,
|
||||
python::def( "getStack", &getCurrentStack,
|
||||
"Return a current stack as a list of stackFrame objects" );
|
||||
python::def( "getLocals", &getLocals, "Get list of local variables" );
|
||||
python::def( "getFrame", &getCurrentStackFrame,
|
||||
"Return a current stack frame" );
|
||||
python::def( "getLocals", &getLocals,
|
||||
"Get list of local variables" );
|
||||
python::def( "getParams", &getParams,
|
||||
"Get list of function arguments" );
|
||||
|
||||
// breakpoints
|
||||
python::def( "setBp", &setSoftwareBp, setSoftwareBp_( python::args( "offset", "callback" ),
|
||||
@ -426,7 +430,13 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
.def( "name", &CpuReg::name, "The name of the regsiter" )
|
||||
.def( "index", &CpuReg::index, "The index of thr register" );
|
||||
|
||||
python::class_<StackFrame>( "stackFrame",
|
||||
python::class_<ScopeVars,ScopeVarsPtr,boost::noncopyable>( "locals",
|
||||
"Class for access to local vars", python::no_init )
|
||||
.def("__len__", &ScopeVars::getVarCount )
|
||||
.def("__getitem__", &ScopeVars::getVarByIndex )
|
||||
.def("__getitem__", &ScopeVars::getVarByName );
|
||||
|
||||
python::class_<StackFrame, StackFramePtr,boost::noncopyable>( "stackFrame",
|
||||
"Class representing a frame of the call stack", python::no_init )
|
||||
.def_readonly( "instructionOffset", &StackFrame::m_instructionOffset,
|
||||
"Return a frame's instruction offset" )
|
||||
@ -438,8 +448,10 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Return a frame's stack offset" )
|
||||
.def_readonly( "frameNumber", &StackFrame::m_frameNumber,
|
||||
"Return a frame's number" )
|
||||
.def( "getLocals", &StackFrame::getLocals,
|
||||
.add_property( "locals", &StackFrame::getLocals,
|
||||
"Get list of local variables for this stack frame" )
|
||||
.add_property( "params", &StackFrame::getParams,
|
||||
"Get list of function params" )
|
||||
.def( "__str__", &StackFrame::print,
|
||||
"Return stacks frame as a string");
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "stkframe.h"
|
||||
#include "dbgengine.h"
|
||||
#include "localvar.h"
|
||||
#include "module.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -36,14 +36,21 @@ std::string StackFrame::print() const
|
||||
sstream << ", stack= 0x" << std::hex << m_stackOffset;
|
||||
|
||||
return sstream.str();
|
||||
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
python::dict StackFrame::getLocals() const
|
||||
ScopeVarsPtr StackFrame::getLocals()
|
||||
{
|
||||
return getLocalsByFrame( *this );
|
||||
return ScopeVarsPtr( new LocalVars( shared_from_this() ) );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ScopeVarsPtr StackFrame::getParams()
|
||||
{
|
||||
return ScopeVarsPtr( new FunctionParams( shared_from_this() ) );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -63,6 +70,283 @@ ULONG64 StackFrame::getValue(RegRealativeId rri, LONG64 offset /*= 0*/) const
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool IsInDebugRange(
|
||||
SymbolPtr func,
|
||||
ULONG ipRva
|
||||
)
|
||||
{
|
||||
SymbolPtrList lstFuncDebugStart;
|
||||
SymbolPtrList lstFuncDebugEnd;
|
||||
|
||||
try
|
||||
{
|
||||
lstFuncDebugStart = func->findChildren(SymTagFuncDebugStart);
|
||||
if (1 != lstFuncDebugStart.size())
|
||||
{
|
||||
BOOST_ASSERT(lstFuncDebugStart.empty());
|
||||
return true;
|
||||
}
|
||||
|
||||
lstFuncDebugEnd = func->findChildren(SymTagFuncDebugEnd);
|
||||
if (1 != lstFuncDebugEnd.size())
|
||||
{
|
||||
BOOST_ASSERT(lstFuncDebugEnd.empty());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (const SymbolException &except)
|
||||
{
|
||||
DBG_UNREFERENCED_PARAMETER(except);
|
||||
return true;
|
||||
}
|
||||
|
||||
return
|
||||
((*lstFuncDebugStart.begin())->getRva() <= ipRva) &&
|
||||
((*lstFuncDebugEnd.begin())->getRva() >= ipRva);
|
||||
}
|
||||
|
||||
python::object StackFrame::getLocalByName( const std::string& name )
|
||||
{
|
||||
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 (; itVar != symList.end(); ++itVar)
|
||||
{
|
||||
if ( (*itVar)->getName() == name )
|
||||
{
|
||||
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)
|
||||
{
|
||||
if ( (*itVar)->getName() == name )
|
||||
{
|
||||
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::getParamByName( const std::string& name )
|
||||
{
|
||||
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 (; itVar != symList.end(); ++itVar)
|
||||
{
|
||||
if ( (*itVar)->getDataKind() == DataIsParam && (*itVar)->getName() == name )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG StackFrame::getLocalCount()
|
||||
{
|
||||
ULONG count = 0;
|
||||
|
||||
ModulePtr mod;
|
||||
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 it;
|
||||
for ( it = symList.begin(); it != symList.end(); it++ )
|
||||
{
|
||||
if ( (*it)->getName() != "" )
|
||||
count++;
|
||||
}
|
||||
|
||||
// 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(); ++itScope)
|
||||
{
|
||||
SymbolPtr scope = *itScope;
|
||||
ULONG scopeRva = scope->getRva();
|
||||
if (scopeRva <= ipRva && (scopeRva + scope->getSize()) > ipRva)
|
||||
{
|
||||
SymbolPtrList symList = scope->findChildren(SymTagData);
|
||||
count += (ULONG)symList.size();
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG StackFrame::getParamCount()
|
||||
{
|
||||
ULONG count = 0;
|
||||
|
||||
ModulePtr mod;
|
||||
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 it;
|
||||
for ( it = symList.begin(); it != symList.end(); it++ )
|
||||
{
|
||||
if ( (*it)->getDataKind() == DataIsParam )
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
python::list getCurrentStack()
|
||||
{
|
||||
std::vector<STACK_FRAME_DESC> frames;
|
||||
@ -72,7 +356,7 @@ python::list getCurrentStack()
|
||||
|
||||
for ( ULONG i = 0; i < frames.size(); ++i )
|
||||
{
|
||||
python::object frameObj( StackFrame( frames.at(i) ) );
|
||||
python::object frameObj( StackFramePtr( new StackFrame( frames.at(i) ) ) );
|
||||
frameList.append( frameObj );
|
||||
}
|
||||
|
||||
@ -81,11 +365,25 @@ python::list getCurrentStack()
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
StackFrame getCurrentStackFrame()
|
||||
StackFramePtr getCurrentStackFrame()
|
||||
{
|
||||
std::vector<STACK_FRAME_DESC> frames;
|
||||
getStackTrace( frames );
|
||||
return frames[0];
|
||||
return StackFramePtr( new StackFrame( frames[0] ) );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ScopeVarsPtr getLocals()
|
||||
{
|
||||
return getCurrentStackFrame()->getLocals();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ScopeVarsPtr getParams()
|
||||
{
|
||||
return getCurrentStackFrame()->getParams();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
105
pykd/stkframe.h
105
pykd/stkframe.h
@ -8,23 +8,52 @@
|
||||
#include "context.h"
|
||||
#include "symengine.h"
|
||||
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace pykd {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class StackFrame
|
||||
class StackFrame;
|
||||
typedef boost::shared_ptr<StackFrame> StackFramePtr;
|
||||
|
||||
class ScopeVars;
|
||||
typedef boost::shared_ptr<ScopeVars> ScopeVarsPtr;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class StackFrame : public boost::enable_shared_from_this<StackFrame>
|
||||
{
|
||||
public:
|
||||
|
||||
StackFrame( const STACK_FRAME_DESC& desc );
|
||||
|
||||
python::dict getLocals() const;
|
||||
ScopeVarsPtr getLocals();
|
||||
|
||||
ScopeVarsPtr getParams();
|
||||
|
||||
std::string print() const;
|
||||
|
||||
ULONG64 getValue(RegRealativeId rri, LONG64 offset = 0) const;
|
||||
|
||||
ULONG getLocalCount();
|
||||
|
||||
ULONG getParamCount();
|
||||
|
||||
python::object getLocalByName( const std::string& name );
|
||||
|
||||
python::object getParamByName( const std::string& name );
|
||||
|
||||
python::object getLocalByIndex( ULONG index ){
|
||||
return python::long_(0);
|
||||
}
|
||||
|
||||
python::object getParamByIndex( ULONG index ){
|
||||
return python::long_(0);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
ULONG m_frameNumber;
|
||||
@ -35,12 +64,82 @@ public:
|
||||
|
||||
};
|
||||
|
||||
class ScopeVars {
|
||||
|
||||
public:
|
||||
|
||||
ScopeVars( StackFramePtr &frame ) :
|
||||
m_frame( frame )
|
||||
{}
|
||||
|
||||
virtual ULONG getVarCount() const = 0;
|
||||
virtual python::object getVarByName( const std::string &name ) = 0;
|
||||
virtual python::object getVarByIndex(ULONG index) const = 0 ;
|
||||
|
||||
protected:
|
||||
|
||||
StackFramePtr m_frame;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LocalVars : public ScopeVars {
|
||||
|
||||
public:
|
||||
|
||||
LocalVars( StackFramePtr &frame ) :
|
||||
ScopeVars( frame )
|
||||
{}
|
||||
|
||||
private:
|
||||
|
||||
ULONG getVarCount() const {
|
||||
return m_frame->getLocalCount();
|
||||
}
|
||||
|
||||
python::object getVarByName( const std::string &name ) {
|
||||
return m_frame->getLocalByName( name );
|
||||
}
|
||||
|
||||
python::object getVarByIndex(ULONG index) const {
|
||||
return m_frame->getLocalByIndex( index );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class FunctionParams : public ScopeVars {
|
||||
|
||||
public:
|
||||
|
||||
FunctionParams( StackFramePtr &frame ) :
|
||||
ScopeVars( frame )
|
||||
{}
|
||||
|
||||
private:
|
||||
|
||||
ULONG getVarCount() const {
|
||||
return m_frame->getParamCount();
|
||||
}
|
||||
|
||||
python::object getVarByName( const std::string &name ) {
|
||||
return m_frame->getParamByName( name );
|
||||
}
|
||||
|
||||
python::object getVarByIndex(ULONG index) const {
|
||||
return python::long_(0L);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
StackFrame getCurrentStackFrame();
|
||||
StackFramePtr getCurrentStackFrame();
|
||||
|
||||
python::list getCurrentStack();
|
||||
|
||||
ScopeVarsPtr getLocals();
|
||||
|
||||
ScopeVarsPtr getParams();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace pykd
|
||||
|
@ -35,10 +35,9 @@ class LocalVarsTest(unittest.TestCase):
|
||||
testEnumWindowsProc1Locals(self, pykd.getLocals())
|
||||
|
||||
pykd.go() # targetapp!EnumWindowsProc1 -> targetapp!functionCalledFromEnumWindowsProc1
|
||||
testEnumWindowsProc1Locals(self, pykd.getCurrentStack()[1].getLocals())
|
||||
testEnumWindowsProc1Locals(self, pykd.getStack()[1].locals )
|
||||
|
||||
pykd.go() # targetapp!EnumWindowsProc1 -> targetapp!EnumWindowsProc2
|
||||
locals = pykd.getLocals()
|
||||
self.assertEqual( len(locals), 2 )
|
||||
locValues = locals.values()
|
||||
self.assertTrue( locValues[0] == 7 or locValues[1] == 7 )
|
||||
self.assertTrue( locals[0] == 7 or locals[1] == 7 )
|
||||
|
@ -63,11 +63,11 @@ class ModuleTest( unittest.TestCase ):
|
||||
fileName = pykd.getSourceFile(target.module.FuncWithName0 )
|
||||
self.assertTrue( re.search('targetapp\\.cpp', fileName ) )
|
||||
fileName, lineNo, displacement = pykd.getSourceLine( target.module.FuncWithName0 + 2)
|
||||
self.assertEqual( 382, lineNo )
|
||||
self.assertEqual( 393, lineNo )
|
||||
self.assertTrue( re.search('targetapp\\.cpp', fileName ) )
|
||||
self.assertEqual( 2, displacement )
|
||||
fileName, lineNo, displacement = pykd.getSourceLine()
|
||||
self.assertEqual( 624, lineNo )
|
||||
self.assertEqual( 639, lineNo )
|
||||
|
||||
def testEnumSymbols( self ):
|
||||
lst = target.module.enumSymbols()
|
||||
|
@ -81,6 +81,13 @@ class TypeInfoTest( unittest.TestCase ):
|
||||
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() )
|
||||
@ -198,7 +205,12 @@ class TypeInfoTest( unittest.TestCase ):
|
||||
self.assertNotEqual( 0, ti.m_stdstr.staticOffset() )
|
||||
|
||||
def testUdtSubscribe(self):
|
||||
tv = pykd.typeInfo( "g_virtChild" )
|
||||
self.assertEqual( 5, len(tv) )
|
||||
for field in tv:
|
||||
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) )
|
||||
|
||||
|
@ -84,6 +84,16 @@ struct structTest {
|
||||
structTest* m_field4;
|
||||
};
|
||||
|
||||
struct structNullSize {
|
||||
};
|
||||
|
||||
structNullSize* g_nullSizeArray = 0;
|
||||
|
||||
struct structAbstract;
|
||||
typedef struct structAbstract *pstructAbstract;
|
||||
|
||||
pstructAbstract g_structAbstract = 0;
|
||||
|
||||
structWithBits g_structWithBits = { 4, 1, 3};
|
||||
|
||||
structTest g_structTest = { 0, 500, true, 1, NULL };
|
||||
@ -435,6 +445,9 @@ void FuncWithName0()
|
||||
|
||||
std::cout << g_structTypeDef.m_field0;
|
||||
|
||||
std::cout << g_nullSizeArray;
|
||||
std::cout << g_structAbstract;
|
||||
|
||||
//std::cout << g_virtChild.VirtualBaseClass1::m_baseField;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user