[0.3.x] added : cpu context class

git-svn-id: https://pykd.svn.codeplex.com/svn@84225 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2013-07-09 08:12:26 +00:00 committed by Mikhail I. Izmestev
parent 8eb0ba0584
commit 17dbcecbe9
10 changed files with 118 additions and 54 deletions

29
pykd/cpucontext.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "stdafx.h"
#include "cpucontext.h"
#include "variant.h"
namespace pykd {
///////////////////////////////////////////////////////////////////////////////
python::object CPUContextAdaptor::getRegisterByName( kdlib::CPUContext& cpu, const std::wstring &name )
{
kdlib::NumVariant var = cpu.getRegisterByName(name);
return NumVariantAdaptor::convertToPython( var );
}
///////////////////////////////////////////////////////////////////////////////
python::object CPUContextAdaptor::getRegisterByIndex( kdlib::CPUContext& cpu, size_t index )
{
kdlib::NumVariant var = cpu.getRegisterByIndex(index);
std::wstring name = cpu.getRegisterName(index);
return python::make_tuple( name, NumVariantAdaptor::convertToPython( var ) );
}
///////////////////////////////////////////////////////////////////////////////
} // end namespace pykd

22
pykd/cpucontext.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include <boost/python/tuple.hpp>
namespace python = boost::python;
#include "kdlib/dbgengine.h"
#include "kdlib/cpucontext.h"
namespace pykd {
///////////////////////////////////////////////////////////////////////////////
class CPUContextAdaptor
{
public:
static python::object getRegisterByName( kdlib::CPUContext& cpu, const std::wstring &name );
static python::object getRegisterByIndex( kdlib::CPUContext& cpu, size_t index );
};
///////////////////////////////////////////////////////////////////////////////
} //end namespace pykd

View File

@ -142,7 +142,23 @@ kdlib::DebugCallbackResult EventHandler::onBreakpoint( kdlib::BREAKPOINT_ID bpId
break;
}
return pythonHandler(bpId );
python::object resObj = pythonHandler( bpId );
if ( resObj.is_none() )
{
result = kdlib::DebugCallbackNoChange;
break;
}
int retVal = python::extract<int>( resObj );
if ( retVal >= kdlib::DebugCallbackMax )
{
result = kdlib::DebugCallbackBreak;
break;
}
result = kdlib::DebugCallbackResult(retVal);
} while( FALSE );

View File

@ -123,6 +123,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="cpucontext.h" />
<ClInclude Include="dbgengine.h" />
<ClInclude Include="dbgexcept.h" />
<ClInclude Include="eventhandler.h" />
@ -137,6 +138,7 @@
<ClInclude Include="windbgext.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="cpucontext.cpp" />
<ClCompile Include="dbgengine.cpp" />
<ClCompile Include="dbgexcept.cpp" />
<ClCompile Include="dllmain.cpp">

View File

@ -51,6 +51,9 @@
<ClInclude Include="eventhandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cpucontext.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@ -74,6 +77,9 @@
<ClCompile Include="eventhandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cpucontext.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="pykd.def">

View File

@ -1,6 +1,7 @@
#include "stdafx.h"
#include <boost/bind.hpp>
#include "kdlib/kdlib.h"
@ -13,6 +14,7 @@
#include "typedvar.h"
#include "windbgext.h"
#include "eventhandler.h"
#include "cpucontext.h"
using namespace pykd;
@ -244,6 +246,7 @@ BOOST_PYTHON_MODULE( pykd )
"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" );
// // CPU registers
// python::def( "reg", &getRegByName,
// "Return a CPU regsiter value by the register's name" );
@ -294,10 +297,10 @@ BOOST_PYTHON_MODULE( pykd )
// "Set implicit thread for current process" );
// python::def( "getProcessThreads", &pysupport::getProcessThreads,
// "Get all process's threads ( user mode only )" );
python::def( "getCurrentProcessId", &kdlib::getCurrentProcessId,
"Return PID of the current process ( user mode only )" );
python::def( "getCurrentThreadId", &kdlib::getCurrentThreadId,
"Return TID of the current thread ( user mode only )" );
//python::def( "getCurrentProcessId", &kdlib::getCurrentProcessId,
// "Return PID of the current process ( user mode only )" );
//python::def( "getCurrentThreadId", &kdlib::getCurrentThreadId,
// "Return TID of the current thread ( user mode only )" );
// python::def( "getCurrentProcessExeName", &getCurrentProcessExecutableName,
// "Return name of executable file loaded in the current process");
@ -510,6 +513,16 @@ BOOST_PYTHON_MODULE( pykd )
;
python::class_<kdlib::CPUContext, kdlib::CPUContextPtr, boost::noncopyable>( "cpu",
"class for CPU context representation", python::no_init )
.def("__init__", python::make_constructor(&kdlib::loadCPUCurrentContext) )
.def("__init__", python::make_constructor(&kdlib::loadCPUContextByIndex) )
.add_property("ip", &kdlib::CPUContext::getIP )
.add_property("sp", &kdlib::CPUContext::getSP )
.add_property("fp", &kdlib::CPUContext::getSP )
.def("__getattr__", &CPUContextAdaptor::getRegisterByName )
.def("__getitem__", &CPUContextAdaptor::getRegisterByIndex );
// python::class_<CpuReg, python::bases<intBase> >(
// "cpuReg", "CPU regsiter class", boost::python::no_init )

View File

@ -37,10 +37,8 @@ public:
return var;
}
static python::object NumVariantAdaptor::convertToPython( kdlib::NumBehavior& num )
static python::object NumVariantAdaptor::convertToPython( kdlib::NumVariant& var )
{
kdlib::NumVariant var = kdlib::NumVariant( num );
if ( var.isChar() )
return python::object( var.asInt() );
@ -80,6 +78,13 @@ public:
return python::object( var.asInt() );
}
static python::object NumVariantAdaptor::convertToPython( kdlib::NumBehavior& num )
{
kdlib::NumVariant var = kdlib::NumVariant( num );
return convertToPython( var );
}
public:
static python::object eq( kdlib::NumBehavior& var, python::object& obj ) {

View File

@ -14,10 +14,10 @@ class callCounter:
return self.func(val)
def stopOnBreak(id):
return pykd.Break
return pykd.eventResult.Break
def continueOnBreak(id):
return pykd.NoChange
return pykd.eventResult.Proceed
class BreakpointTest( unittest.TestCase ):

View File

@ -19,9 +19,8 @@ import moduletest
import typeinfo
import typedvar
import breakpoint
import regtest
#import regtest
#import mspdbtest
#import localstest
#import customtypestest
@ -54,13 +53,15 @@ def getTestSuite( singleName = "" ):
unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ),
unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ),
#unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ),
unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ),
#unittest.TestLoader().loadTestsFromTestCase( customtypestest.CustomTypesTest ),
# ^^^
unittest.TestLoader().loadTestsFromTestCase( TerminateProcessTest ),
unittest.TestLoader().loadTestsFromTestCase( breakpoint.BreakpointTest ),
#unittest.TestLoader().loadTestsFromTestCase( mspdbtest.MsPdbTest ),
#unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest ),
#unittest.TestLoader().loadTestsFromTestCase( ehexcepttest.EhExceptionTest ),

View File

@ -4,47 +4,17 @@ 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 testCtor(self):
currentcpu = pykd.cpu()
cpu0 = pykd.cpu(0)
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" )
def testIp(self):
currentcpu = pykd.cpu()
self.assertNotEqual( 0, currentcpu.ip )
self.assertNotEqual( 0, currentcpu.sp )
self.assertNotEqual( 0, currentcpu.fp )
def testRegEnum(self):
for r in pykd.cpu():
pass