From 8a41abcd13897f81de0b62fab03d0a203c66511d Mon Sep 17 00:00:00 2001
From: "SND\\kernelnet_cp"
 <SND\kernelnet_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Fri, 17 Aug 2012 07:08:33 +0000
Subject: [PATCH] [0.2.x] added : step, trace routines

git-svn-id: https://pykd.svn.codeplex.com/svn@78896 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/dbgengine.h    |  2 ++
 pykd/pymod.cpp      |  7 ++++++
 pykd/win/dbgeng.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 65 insertions(+)

diff --git a/pykd/dbgengine.h b/pykd/dbgengine.h
index bbed4cc..5f004f0 100644
--- a/pykd/dbgengine.h
+++ b/pykd/dbgengine.h
@@ -16,6 +16,8 @@ bool isDumpAnalyzing();
 bool isKernelDebugging();
 
 void debugGo();
+void debugStep();
+void debugStepIn();
 void debugBreak();
 ULONG64 evaluate( const std::wstring  &expression );
 
diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp
index 96420cc..cf25e60 100644
--- a/pykd/pymod.cpp
+++ b/pykd/pymod.cpp
@@ -21,6 +21,7 @@
 #include "localvar.h"
 
 #include "win/dbgio.h"
+#include "win/windbg.h"
 
 using namespace pykd;
 
@@ -72,6 +73,8 @@ BOOST_PYTHON_MODULE( pykd )
         "Check if it is a dump analyzing ( not living debuggee )" );
     python::def( "isKernelDebugging", &isKernelDebugging,
         "Check if kernel dubugging is running" );
+    python::def( "isWindbgExt", &WindbgGlobalSession::isInit,
+        "Check if script works in windbg context" );
 
     python::def( "breakin", &debugBreak,
         "Break into debugger" );
@@ -79,6 +82,10 @@ BOOST_PYTHON_MODULE( pykd )
         "Evaluate windbg expression" );
     python::def( "go", &debugGo,
         "Go debugging"  );
+    python::def( "step", &debugStep,
+        "The target is executing a single instruction or--if that instruction is a subroutine call--subroutine" );
+    python::def( "trace", &debugStepIn,
+        "The target is executing a single instruction" );
 
     // Debug output
     python::def( "dprint", &pykd::dprint, dprint_( boost::python::args( "str", "dml" ), 
diff --git a/pykd/win/dbgeng.cpp b/pykd/win/dbgeng.cpp
index 6de7deb..beaf65c 100644
--- a/pykd/win/dbgeng.cpp
+++ b/pykd/win/dbgeng.cpp
@@ -170,6 +170,62 @@ void debugGo()
 
 ///////////////////////////////////////////////////////////////////////////////
 
+void debugStep()
+{
+    PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
+
+    HRESULT     hres;
+
+    hres = g_dbgEng->control->SetExecutionStatus( DEBUG_STATUS_STEP_OVER );
+
+    if ( FAILED( hres ) )
+        throw DbgException( "IDebugControl::SetExecutionStatus failed" );
+
+    ULONG    currentStatus;
+
+    do {
+        hres = g_dbgEng->control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);
+        if ( FAILED( hres ) )
+            throw DbgException( "IDebugControl::WaitForEvent failed" );
+
+        hres = g_dbgEng->control->GetExecutionStatus( &currentStatus );
+
+        if ( FAILED( hres ) )
+            throw  DbgException( "IDebugControl::GetExecutionStatus  failed" ); 
+
+    } while( currentStatus != DEBUG_STATUS_BREAK && currentStatus != DEBUG_STATUS_NO_DEBUGGEE );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void debugStepIn()
+{
+    PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
+
+    HRESULT     hres;
+
+    hres = g_dbgEng->control->SetExecutionStatus( DEBUG_STATUS_STEP_INTO );
+
+    if ( FAILED( hres ) )
+        throw DbgException( "IDebugControl::SetExecutionStatus failed" );
+
+    ULONG    currentStatus;
+
+    do {
+        hres = g_dbgEng->control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);
+        if ( FAILED( hres ) )
+            throw DbgException( "IDebugControl::WaitForEvent failed" );
+
+        hres = g_dbgEng->control->GetExecutionStatus( &currentStatus );
+
+        if ( FAILED( hres ) )
+            throw  DbgException( "IDebugControl::GetExecutionStatus  failed" ); 
+
+    } while( currentStatus != DEBUG_STATUS_BREAK && currentStatus != DEBUG_STATUS_NO_DEBUGGEE );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 void debugBreak()
 {
     PyThreadState   *pystate = PyEval_SaveThread();