fixed: #29 (support for inline in stack)

This commit is contained in:
ussrhero 2019-04-29 22:07:50 +03:00
parent 850e986a03
commit d47d70d71a
4 changed files with 68 additions and 6 deletions

View File

@ -69,14 +69,14 @@ std::wstring getRegisterName(unsigned long index)
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
python::list getCurrentStack() python::list getStack(bool inlineFrames)
{ {
kdlib::StackPtr stack; kdlib::StackPtr stack;
unsigned long numberFrames; unsigned long numberFrames;
do { do {
AutoRestorePyState pystate; AutoRestorePyState pystate;
stack = kdlib::getStack(); stack = kdlib::getStack(inlineFrames);
numberFrames = stack->getFrameCount(); numberFrames = stack->getFrameCount();
} while(false); } while(false);
@ -242,6 +242,23 @@ python::dict StackFrameAdapter::getLocalsDict(kdlib::StackFramePtr& frame)
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
python::tuple StackFrameAdapter::findSymbol(kdlib::StackFramePtr& frame)
{
kdlib::MEMDISPLACEMENT displacement;
std::wstring symbolName;
std::wstring moduleName;
{
AutoRestorePyState pystate;
symbolName = frame->findSymbol(displacement);
moduleName = kdlib::getModuleName(kdlib::findModuleBase(frame->getIP()));
}
return python::make_tuple(moduleName, symbolName, displacement);
}
///////////////////////////////////////////////////////////////////////////////
python::tuple CPUContextAdapter::getRegisterByIndex(unsigned long index) python::tuple CPUContextAdapter::getRegisterByIndex(unsigned long index)
{ {

View File

@ -70,6 +70,8 @@ public:
AutoRestorePyState pystate; AutoRestorePyState pystate;
frame->switchTo(); frame->switchTo();
} }
static python::tuple findSymbol(kdlib::StackFramePtr& frame);
}; };
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
@ -157,7 +159,7 @@ inline void switchProcessorMode() {
kdlib::switchCPUMode(); kdlib::switchCPUMode();
} }
python::list getCurrentStack(); python::list getStack(bool inlineFrames = false);
inline kdlib::StackFramePtr getCurrentFrame() { inline kdlib::StackFramePtr getCurrentFrame() {
AutoRestorePyState pystate; AutoRestorePyState pystate;

View File

@ -78,6 +78,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceFile_, pykd::getSourceFile, 0, 1 );
BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceFileFromSrcSrv_, pykd::getSourceFileFromSrcSrv, 0, 1 ); BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceFileFromSrcSrv_, pykd::getSourceFileFromSrcSrv, 0, 1 );
BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceLine_, pykd::getSourceLine, 0, 1 ); BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceLine_, pykd::getSourceLine, 0, 1 );
BOOST_PYTHON_FUNCTION_OVERLOADS( findSymbol_, pykd::findSymbol, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( findSymbol_, pykd::findSymbol, 1, 2 );
BOOST_PYTHON_FUNCTION_OVERLOADS( getStack_, pykd::getStack, 0, 1);
BOOST_PYTHON_FUNCTION_OVERLOADS( getProcessOffset_, pykd::getProcessOffset, 0, 1); BOOST_PYTHON_FUNCTION_OVERLOADS( getProcessOffset_, pykd::getProcessOffset, 0, 1);
BOOST_PYTHON_FUNCTION_OVERLOADS( getProcessSystemId_, pykd::getProcessSystemId, 0, 1); BOOST_PYTHON_FUNCTION_OVERLOADS( getProcessSystemId_, pykd::getProcessSystemId, 0, 1);
@ -482,8 +483,8 @@ void pykd_init()
"Switch processor mode ( X86 <-> X64 )" ); "Switch processor mode ( X86 <-> X64 )" );
// stack and local variables // stack and local variables
python::def( "getStack", pykd::getCurrentStack, python::def( "getStack", pykd::getStack, getStack_(python::args("inlineFrames"),
"Return a current stack as a list of stackFrame objects" ); "Return a current stack as a list of stackFrame objects" ) );
python::def( "getFrame", pykd::getCurrentFrame, python::def( "getFrame", pykd::getCurrentFrame,
"Return a current stack frame" ); "Return a current stack frame" );
python::def("getFrameNumber", pykd::getCurrentFrameNumber, python::def("getFrameNumber", pykd::getCurrentFrameNumber,
@ -1116,7 +1117,15 @@ void pykd_init()
"return the function's local variable by it's name") "return the function's local variable by it's name")
.def( "switchTo", StackFrameAdapter::switchTo, .def( "switchTo", StackFrameAdapter::switchTo,
"Make this frame a current") "Make this frame a current")
.def( "__str__", StackFrameAdapter::print ); //.def( "isInline", StackFrameAdapter::isInline,
// "this virtual frame of inlined function" )
//.def( "getFunciton", StackFrameAdapter::getFunction,
// "return instance of the typedVar class representing function")
.def( "findSymbol", StackFrameAdapter::findSymbol,
"return symbol for frame's instruction pointer")
//.def( "getSourceLine", StackFrameAdapter::getSourceLine,
// "return source line for stack frame's function" )
.def( "__str__", StackFrameAdapter::print );
python::class_<CPUContextAdapter>("cpu", "class for CPU context representation" ) python::class_<CPUContextAdapter>("cpu", "class for CPU context representation" )
//.def("__init__", python::make_constructor(CPUContextAdapter::getCPUContext) ) //.def("__init__", python::make_constructor(CPUContextAdapter::getCPUContext) )

View File

@ -1,4 +1,7 @@
import unittest import unittest
import os
import sys
import pykd import pykd
import target import target
@ -55,3 +58,34 @@ class StackTest(unittest.TestCase):
self.assertEqual(0, len(topFrame.getLocals())) self.assertEqual(0, len(topFrame.getLocals()))
class InlineStackTest(unittest.TestCase):
def setUp(self):
dumpDir = os.path.join( os.path.dirname(sys.argv[0]), r"..\..\kdlibcpp\kdlib\tests\dumps\targetapp_stacktest_x64_release")
dump_file = os.path.join( dumpDir, "targetapp_stacktest_x64_release.cab" )
self.symbolPath = pykd.getSymbolPath()
symbolPath = self.symbolPath + ";" + dumpDir
pykd.setSymbolPath(symbolPath)
self.dump_id = pykd.loadDump( dump_file )
def tearDown(self):
pykd.closeDump( self.dump_id )
pykd.setSymbolPath(self.symbolPath)
def testGetStack(self):
expectedStack = [
'targetapp!stackTestClass::stackMethod',
'targetapp!stackTestRun2',
'targetapp!stackTestRun1',
'targetapp!stackTestRun']
realStack = []
for frame in pykd.getStack(inlineFrames = True):
moduleName, symbolName, disp = frame.findSymbol()
realStack.append( "%s!%s" % ( moduleName, symbolName ) )
self.assertEqual( expectedStack, realStack[0:4])