From 6d0bb6e9ab99078707abb7dbd4dcabee066175c9 Mon Sep 17 00:00:00 2001
From: "SND\\kernelnet_cp"
 <SND\kernelnet_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Tue, 9 Jul 2013 12:25:00 +0000
Subject: [PATCH] [0.3.x] added : onChangeExecutionState

git-svn-id: https://pykd.svn.codeplex.com/svn@84228 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/dbgengine.cpp    | 42 ++++++++++++++++++++++++++++++++++++++++++
 pykd/dbgengine.h      |  4 ++++
 pykd/eventhandler.cpp | 22 ++++++++++++++++++++++
 pykd/eventhandler.h   |  1 +
 pykd/pymod.cpp        | 42 +++++++++++++++++++++---------------------
 5 files changed, 90 insertions(+), 21 deletions(-)

diff --git a/pykd/dbgengine.cpp b/pykd/dbgengine.cpp
index c7dad89..5478275 100644
--- a/pykd/dbgengine.cpp
+++ b/pykd/dbgengine.cpp
@@ -65,6 +65,48 @@ kdlib::ExecutionStatus targetStepIn()
 
 ///////////////////////////////////////////////////////////////////////////////
 
+kdlib::PROCESS_DEBUG_ID startProcess( const std::wstring  &processName )
+{
+    kdlib::PROCESS_DEBUG_ID  id;
+
+    PyThreadState*    state = PyEval_SaveThread();
+
+    id = kdlib::startProcess(processName);
+
+    PyEval_RestoreThread( state );
+
+    return id;
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+kdlib::PROCESS_DEBUG_ID attachProcess( kdlib::PROCESS_ID pid )
+{
+    kdlib::PROCESS_DEBUG_ID  id;
+
+    PyThreadState*    state = PyEval_SaveThread();
+
+    id = kdlib::attachProcess(pid);
+
+    PyEval_RestoreThread( state );
+
+    return id;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void loadDump( const std::wstring &fileName )
+{
+    PyThreadState*    state = PyEval_SaveThread();
+
+    kdlib::loadDump(fileName);
+
+    PyEval_RestoreThread( state );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 python::tuple getSourceLine( kdlib::MEMOFFSET_64 offset )
 {
     std::wstring  fileName;
diff --git a/pykd/dbgengine.h b/pykd/dbgengine.h
index 22c7c9e..5866d3a 100644
--- a/pykd/dbgengine.h
+++ b/pykd/dbgengine.h
@@ -14,6 +14,10 @@ void targetBreak();
 kdlib::ExecutionStatus targetStep();
 kdlib::ExecutionStatus targetStepIn();
 
+kdlib::PROCESS_DEBUG_ID startProcess( const std::wstring  &processName );
+kdlib::PROCESS_DEBUG_ID attachProcess( kdlib::PROCESS_ID pid );
+void loadDump( const std::wstring &fileName );
+
 python::tuple getSourceLine( kdlib::MEMOFFSET_64 offset = 0 );
 
 python::tuple findSymbolAndDisp( ULONG64 offset );
diff --git a/pykd/eventhandler.cpp b/pykd/eventhandler.cpp
index 4aee170..c886ab8 100644
--- a/pykd/eventhandler.cpp
+++ b/pykd/eventhandler.cpp
@@ -176,4 +176,26 @@ kdlib::DebugCallbackResult EventHandler::onBreakpoint( kdlib::BREAKPOINT_ID bpId
 
 ///////////////////////////////////////////////////////////////////////////////
 
+void EventHandler::onExecutionStatusChange( kdlib::ExecutionStatus executionStatus )
+{
+    PyEval_RestoreThread( m_pystate );
+
+    try {
+
+        python::override pythonHandler = get_override( "onExecutionStatusChange" );
+        if ( pythonHandler )
+        {
+            pythonHandler( executionStatus );
+        }
+    }
+    catch (const python::error_already_set &) 
+    {
+        printException();
+    }
+
+    m_pystate = PyEval_SaveThread();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 } // end namespace pykd
diff --git a/pykd/eventhandler.h b/pykd/eventhandler.h
index a2dc8f9..67d9209 100644
--- a/pykd/eventhandler.h
+++ b/pykd/eventhandler.h
@@ -43,6 +43,7 @@ public:
     EventHandler();
 
     virtual kdlib::DebugCallbackResult onBreakpoint( kdlib::BREAKPOINT_ID bpId );
+    virtual void onExecutionStatusChange( kdlib::ExecutionStatus executionStatus );
 
 private:
 
diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp
index f863722..36fa2ed 100644
--- a/pykd/pymod.cpp
+++ b/pykd/pymod.cpp
@@ -83,15 +83,15 @@ BOOST_PYTHON_MODULE( pykd )
 
    // Manage debug target 
 
-    python::def( "startProcess", &kdlib::startProcess,
+    python::def( "startProcess", &startProcess,
         "Start process for debugging" ); 
-    python::def( "attachProcess", &kdlib::attachProcess,
+    python::def( "attachProcess", &attachProcess,
         "Attach debugger to a exsisting process" );
     python::def( "detachProcess", &kdlib::detachProcess, detachProcess_( boost::python::args( "pid" ),
         "Stop process debugging") ); 
     python::def( "killProcess", &kdlib::terminateProcess, terminateProcess_( boost::python::args( "pid" ),
         "Stop debugging and terminate current process" ) );
-    python::def( "loadDump", &kdlib::loadDump,
+    python::def( "loadDump", &loadDump,
         "Load crash dump");
     python::def( "isDumpAnalyzing", &kdlib::isDumpAnalyzing,
         "Check if it is a dump analyzing ( not living debuggee )" );
@@ -616,21 +616,21 @@ BOOST_PYTHON_MODULE( pykd )
    //     "Function reads the kernel bug check code and related parameters\n"
    //     "And return tuple: (code, arg1, arg2, arg3, arg4)" );
 
-   // python::class_<Disasm>("disasm", "Class disassemble a processor instructions" )
-   //     .def( python::init<>( "constructor" ) )
-   //     .def( python::init<ULONG64>( boost::python::args("offset"), "constructor" ) )
-   //     .def( "disasm", &Disasm::disassemble, "Disassemble next instruction" )
-   //     .def( "disasm", &Disasm::jump, "Disassemble from the specified offset" )
-   //     .def( "asm", &Disasm::assembly, "Insert assemblied instuction to current offset" )
-   //     .def( "begin", &Disasm::begin, "Return begin offset" )
-   //     .def( "current", &Disasm::current, "Return current offset" )
-   //     .def( "length", &Disasm::length, "Return current instruction length" )
-   //     .def( "instruction", &Disasm::instruction, "Returm current disassembled instruction" )
-   //     .def( "ea", &Disasm::ea, "Return effective address for last disassembled instruction or 0" )
-   //     .def( "reset", &Disasm::reset, "Reset current offset to begin" )
-   //     .def( "findOffset", &Disasm::getNearInstruction, "Return the location of a processor instruction relative to a given location" )
-   //     .def( "jump", &Disasm::jump, "Change the current instruction" )
-   //     .def( "jumprel", &Disasm::jumprel, "Change the current instruction" );
+    python::class_<kdlib::Disasm>("disasm", "Class disassemble a processor instructions" )
+        .def( python::init<>( "constructor" ) )
+        .def( python::init<ULONG64>( boost::python::args("offset"), "constructor" ) )
+        .def( "disasm", &kdlib::Disasm::disassemble, "Disassemble next instruction" )
+        .def( "disasm", &kdlib::Disasm::jump, "Disassemble from the specified offset" )
+        .def( "asm", &kdlib::Disasm::assembly, "Insert assemblied instuction to current offset" )
+        .def( "begin", &kdlib::Disasm::begin, "Return begin offset" )
+        .def( "current", &kdlib::Disasm::current, "Return current offset" )
+        .def( "length", &kdlib::Disasm::length, "Return current instruction length" )
+        .def( "instruction", &kdlib::Disasm::instruction, "Returm current disassembled instruction" )
+        .def( "ea", &kdlib::Disasm::ea, "Return effective address for last disassembled instruction or 0" )
+        .def( "reset", &kdlib::Disasm::reset, "Reset current offset to begin" )
+        .def( "findOffset", &kdlib::Disasm::getNearInstruction, "Return the location of a processor instruction relative to a given location" )
+        .def( "jump", &kdlib::Disasm::jump, "Change the current instruction" )
+        .def( "jumprel", &kdlib::Disasm::jumprel, "Change the current instruction" );
 
 
     python::enum_<kdlib::DebugCallbackResult>("eventResult", "Return value of event handler")
@@ -660,9 +660,9 @@ BOOST_PYTHON_MODULE( pykd )
    //     .def( "onException", &EventHandlerWrap::OnException,
    //         "Triggered exception event. Parameter - exceptionInfo\n"
    //         "For ignore event method must return eventResult.noChange" )
-   //     .def( "onExecutionStatusChange", &EventHandlerWrap::onExecutionStatusChange,
-   //         "Triggered execution status changed. Parameter - execution status.\n"
-   //         "There is no return value" )
+        .def( "onExecutionStatusChange", &EventHandler::onExecutionStatusChange,
+            "Triggered execution status changed. Parameter - execution status.\n"
+            "There is no return value" )
    //     .def( "onSymbolsLoaded", &EventHandlerWrap::onSymbolsLoaded,
    //         "Triggered debug symbols loaded. Parameter - module base or 0\n"
    //         "There is no return value")