[0.1.x] added : dbgCommand routine

git-svn-id: https://pykd.svn.codeplex.com/svn@70294 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-10-10 14:35:43 +00:00 committed by Mikhail I. Izmestev
parent ee60976466
commit a452624559
10 changed files with 277 additions and 182 deletions

View File

@ -49,6 +49,10 @@ public:
static static
DebugClientPtr setDbgClientCurrent( DebugClientPtr newDbgClient ); DebugClientPtr setDbgClientCurrent( DebugClientPtr newDbgClient );
public:
std::string dbgCommand( const std::wstring &command );
void loadDump( const std::wstring &fileName ); void loadDump( const std::wstring &fileName );
void startProcess( const std::wstring &processName ); void startProcess( const std::wstring &processName );

View File

@ -1,132 +1,180 @@
#include "stdafx.h" #include "stdafx.h"
#include <boost/format.hpp>
#include "dbgext.h"
#include "dbgcmd.h" #include "dbgcmd.h"
#include "dbgexcept.h" #include "dbgclient.h"
#include "dbgio.h"
#include "dbgsystem.h"
/////////////////////////////////////////////////////////////////////////////// namespace pykd {
std::string /////////////////////////////////////////////////////////////////////////////////
dbgCommand( const std::wstring &command )
std::string DebugClient::dbgCommand( const std::wstring &command )
{ {
HRESULT hres; HRESULT hres;
OutputReader outReader( dbgExt->client ); OutputReader outReader( m_client );
{
PyThread_StateRestore pyThreadRestore; PyThreadState *pystate = PyEval_SaveThread();
hres = m_control->ExecuteWide( DEBUG_OUTCTL_THIS_CLIENT, command.c_str(), 0 );
PyEval_RestoreThread( pystate );
hres = dbgExt->control4->ExecuteWide( DEBUG_OUTCTL_THIS_CLIENT, command.c_str(), 0 );
}
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException( "IDebugControl::Execute failed" ); throw DbgException( "IDebugControl::Execute failed" );
return std::string( outReader.Line() ); return std::string( outReader.Line() );
} }
/////////////////////////////////////////////////////////////////////////////// std::string dbgCommand( const std::wstring &command )
dbgExtensionClass::dbgExtensionClass( const char* path ) : m_path(path)
{ {
HRESULT hres; return g_dbgClient->dbgCommand( command );
hres = dbgExt->control->AddExtension( path, 0, &m_handle );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::AddExtension failed" );
} }
/////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
dbgExtensionClass::~dbgExtensionClass() } // end namespace pykd
{
if ( m_handle )
dbgExt->control->RemoveExtension( m_handle );
}
///////////////////////////////////////////////////////////////////////////////
std::string
dbgExtensionClass::call( const std::string &command, const std::string params )
{
HRESULT hres;
OutputReader outReader( dbgExt->client );
hres = dbgExt->control->CallExtension( m_handle, command.c_str(), params.c_str() );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::CallExtension failed" );
return std::string( outReader.Line() );
}
///////////////////////////////////////////////////////////////////////////////
std::string
dbgExtensionClass::print() const
{
return m_handle ? m_path : "";
}
///////////////////////////////////////////////////////////////////////////////
ULONG64
evaluate( const std::string &expression )
{
HRESULT hres;
ULONG64 value = 0;
DEBUG_VALUE debugValue = {};
ULONG remainderIndex = 0;
if ( is64bitSystem() ) //#include <boost/format.hpp>
{ //
hres = dbgExt->control->Evaluate( //#include "dbgext.h"
expression.c_str(), //#include "dbgcmd.h"
DEBUG_VALUE_INT64, //#include "dbgexcept.h"
&debugValue, //#include "dbgio.h"
&remainderIndex ); //#include "dbgsystem.h"
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::Evaluate failed" );
if ( remainderIndex == expression.length() )
value = debugValue.I64;
}
else
{
hres = dbgExt->control->Evaluate(
expression.c_str(),
DEBUG_VALUE_INT32,
&debugValue,
&remainderIndex );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::Evaluate failed" );
if ( remainderIndex == expression.length() )
value = debugValue.I32;
}
return value; /////////////////////////////////////////////////////////////////////////////////
} //
//std::string
/////////////////////////////////////////////////////////////////////////////// //dbgCommand( const std::wstring &command )
//{
void // HRESULT hres;
breakin() //
{ // OutputReader outReader( dbgExt->client );
HRESULT hres; // {
// PyThread_StateRestore pyThreadRestore;
{ //
PyThread_StateRestore pyThreadRestore; // hres = dbgExt->control4->ExecuteWide( DEBUG_OUTCTL_THIS_CLIENT, command.c_str(), 0 );
hres = dbgExt->control->SetInterrupt( DEBUG_INTERRUPT_ACTIVE ); // }
} // if ( FAILED( hres ) )
// throw DbgException( "IDebugControl::Execute failed" );
if ( FAILED( hres ) ) //
throw DbgException( "IDebugControl::SetInterrupt" ); // return std::string( outReader.Line() );
} //}
//
/////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
//
//dbgExtensionClass::dbgExtensionClass( const char* path ) : m_path(path)
//{
// HRESULT hres;
//
// hres = dbgExt->control->AddExtension( path, 0, &m_handle );
// if ( FAILED( hres ) )
// throw DbgException( "IDebugControl::AddExtension failed" );
//}
//
/////////////////////////////////////////////////////////////////////////////////
//
//dbgExtensionClass::~dbgExtensionClass()
//{
// if ( m_handle )
// dbgExt->control->RemoveExtension( m_handle );
//}
//
/////////////////////////////////////////////////////////////////////////////////
//
//std::string
//dbgExtensionClass::call( const std::string &command, const std::string params )
//{
// HRESULT hres;
//
// OutputReader outReader( dbgExt->client );
//
// hres = dbgExt->control->CallExtension( m_handle, command.c_str(), params.c_str() );
// if ( FAILED( hres ) )
// throw DbgException( "IDebugControl::CallExtension failed" );
//
// return std::string( outReader.Line() );
//}
//
/////////////////////////////////////////////////////////////////////////////////
//
//std::string
//dbgExtensionClass::print() const
//{
// return m_handle ? m_path : "";
//}
//
/////////////////////////////////////////////////////////////////////////////////
//
//ULONG64
//evaluate( const std::string &expression )
//{
// HRESULT hres;
// ULONG64 value = 0;
//
// DEBUG_VALUE debugValue = {};
// ULONG remainderIndex = 0;
//
// if ( is64bitSystem() )
// {
// hres = dbgExt->control->Evaluate(
// expression.c_str(),
// DEBUG_VALUE_INT64,
// &debugValue,
// &remainderIndex );
//
// if ( FAILED( hres ) )
// throw DbgException( "IDebugControl::Evaluate failed" );
//
// if ( remainderIndex == expression.length() )
// value = debugValue.I64;
// }
// else
// {
// hres = dbgExt->control->Evaluate(
// expression.c_str(),
// DEBUG_VALUE_INT32,
// &debugValue,
// &remainderIndex );
//
// if ( FAILED( hres ) )
// throw DbgException( "IDebugControl::Evaluate failed" );
//
// if ( remainderIndex == expression.length() )
// value = debugValue.I32;
// }
//
// return value;
//}
//
/////////////////////////////////////////////////////////////////////////////////
//
//void
//breakin()
//{
// HRESULT hres;
//
// {
// PyThread_StateRestore pyThreadRestore;
// hres = dbgExt->control->SetInterrupt( DEBUG_INTERRUPT_ACTIVE );
// }
//
// if ( FAILED( hres ) )
// throw DbgException( "IDebugControl::SetInterrupt" );
//}
//
/////////////////////////////////////////////////////////////////////////////////

View File

@ -1,86 +1,103 @@
#pragma once #pragma once
#include <string>
#include <map>
#include "pyaux.h"
///////////////////////////////////////////////////////////////////////////////// namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
std::string std::string
dbgCommand( const std::wstring &command ); dbgCommand( const std::wstring &command );
template <ULONG status> ///////////////////////////////////////////////////////////////////////////////////
void
setExecutionStatus()
{
HRESULT hres;
hres = dbgExt->control->SetExecutionStatus( status ); }; // end of namespace pykd
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::SetExecutionStatus failed" );
ULONG currentStatus;
do {
{
PyThread_StateRestore pyThreadRestore;
hres = dbgExt->control->WaitForEvent( 0, INFINITE );
}
if ( FAILED( hres ) )
{
if (E_UNEXPECTED == hres)
throw WaitEventException();
throw DbgException( "IDebugControl::WaitForEvent failed" );
}
hres = dbgExt->control->GetExecutionStatus( &currentStatus );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetExecutionStatus failed" );
} while( currentStatus != DEBUG_STATUS_BREAK && currentStatus != DEBUG_STATUS_NO_DEBUGGEE );
}
/////////////////////////////////////////////////////////////////////////////////
class dbgExtensionClass {
public:
dbgExtensionClass() :
m_handle( NULL )
{}
dbgExtensionClass( const char* path );
~dbgExtensionClass();
std::string
call( const std::string &command, const std::string param );
std::string
print() const;
private:
ULONG64 m_handle;
std::string m_path;
};
/////////////////////////////////////////////////////////////////////////////////
ULONG64
evaluate( const std::string &expression );
/////////////////////////////////////////////////////////////////////////////////
void
breakin();
///////////////////////////////////////////////////////////////////////////////// //#include <string>
//#include <map>
//#include "pyaux.h"
///////////////////////////////////////////////////////////////////////////////////
//
//std::string
//dbgCommand( const std::wstring &command );
//
//template <ULONG status>
//void
//setExecutionStatus()
//{
// HRESULT hres;
//
// hres = dbgExt->control->SetExecutionStatus( status );
//
// if ( FAILED( hres ) )
// throw DbgException( "IDebugControl::SetExecutionStatus failed" );
//
// ULONG currentStatus;
//
// do {
//
// {
// PyThread_StateRestore pyThreadRestore;
// hres = dbgExt->control->WaitForEvent( 0, INFINITE );
// }
//
// if ( FAILED( hres ) )
// {
// if (E_UNEXPECTED == hres)
// throw WaitEventException();
//
// throw DbgException( "IDebugControl::WaitForEvent failed" );
// }
//
// hres = dbgExt->control->GetExecutionStatus( &currentStatus );
//
// if ( FAILED( hres ) )
// throw DbgException( "IDebugControl::GetExecutionStatus failed" );
//
// } while( currentStatus != DEBUG_STATUS_BREAK && currentStatus != DEBUG_STATUS_NO_DEBUGGEE );
//
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//class dbgExtensionClass {
//
//public:
//
// dbgExtensionClass() :
// m_handle( NULL )
// {}
//
// dbgExtensionClass( const char* path );
//
// ~dbgExtensionClass();
//
// std::string
// call( const std::string &command, const std::string param );
//
// std::string
// print() const;
//
//private:
//
// ULONG64 m_handle;
// std::string m_path;
//};
//
//
///////////////////////////////////////////////////////////////////////////////////
//
//ULONG64
//evaluate( const std::string &expression );
//
///////////////////////////////////////////////////////////////////////////////////
//
//void
//breakin();
//
///////////////////////////////////////////////////////////////////////////////////

View File

@ -11,6 +11,7 @@
#include "dbgclient.h" #include "dbgclient.h"
#include "dbgio.h" #include "dbgio.h"
#include "dbgpath.h" #include "dbgpath.h"
#include "dbgcmd.h"
using namespace pykd; using namespace pykd;
@ -68,6 +69,8 @@ BOOST_PYTHON_MODULE( pykd )
"Return instance of Module class" ) "Return instance of Module class" )
.def( "findModule", &pykd::DebugClient::findModule, .def( "findModule", &pykd::DebugClient::findModule,
"Return instance of the Module class which posseses specified address" ) "Return instance of the Module class which posseses specified address" )
.def( "dbgCommand", &pykd::DebugClient::dbgCommand,
"Run a debugger's command and return it's result as a string" )
.def( "dprint", &pykd::DebugClient::dprint, .def( "dprint", &pykd::DebugClient::dprint,
"Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" ) "Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" )
.def( "dprintln", &pykd::DebugClient::dprintln, .def( "dprintln", &pykd::DebugClient::dprintln,
@ -87,6 +90,8 @@ BOOST_PYTHON_MODULE( pykd )
"Return instance of Module class" ); "Return instance of Module class" );
python::def( "findModule", &pykd::findModule, python::def( "findModule", &pykd::findModule,
"Return instance of the Module class which posseses specified address" ); "Return instance of the Module class which posseses specified address" );
python::def( "dbgCommand", &pykd::dbgCommand,
"Run a debugger's command and return it's result as a string" ),
python::def( "dprint", &pykd::dprint, dprint_( boost::python::args( "str", "dml" ), python::def( "dprint", &pykd::dprint, dprint_( boost::python::args( "str", "dml" ),
"Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" ) ); "Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
python::def( "dprintln", &pykd::dprintln, dprintln_( boost::python::args( "str", "dml" ), python::def( "dprintln", &pykd::dprintln, dprintln_( boost::python::args( "str", "dml" ),

View File

@ -65,7 +65,6 @@ public:
~OutputReader() ~OutputReader()
{ {
if ( m_previousCallback )
m_client->SetOutputCallbacks( m_previousCallback ); m_client->SetOutputCallbacks( m_previousCallback );
} }

View File

@ -353,6 +353,10 @@
RelativePath=".\dbgclient.cpp" RelativePath=".\dbgclient.cpp"
> >
</File> </File>
<File
RelativePath=".\dbgcmd.cpp"
>
</File>
<File <File
RelativePath=".\dbgexcept.cpp" RelativePath=".\dbgexcept.cpp"
> >
@ -439,6 +443,10 @@
RelativePath=".\dbgclient.h" RelativePath=".\dbgclient.h"
> >
</File> </File>
<File
RelativePath=".\dbgcmd.h"
>
</File>
<File <File
RelativePath=".\dbgexcept.h" RelativePath=".\dbgexcept.h"
> >

View File

@ -18,7 +18,6 @@ class BaseTest( unittest.TestCase ):
self.assertTrue( hasattr(pykd, 'breakin') ) self.assertTrue( hasattr(pykd, 'breakin') )
self.assertTrue( hasattr(pykd, 'compareMemory') ) self.assertTrue( hasattr(pykd, 'compareMemory') )
self.assertTrue( hasattr(pykd, 'containingRecord') ) self.assertTrue( hasattr(pykd, 'containingRecord') )
self.assertTrue( hasattr(pykd, 'createSession') )
self.assertTrue( hasattr(pykd, 'dbgCommand') ) self.assertTrue( hasattr(pykd, 'dbgCommand') )
self.assertTrue( hasattr(pykd, 'dprint') ) self.assertTrue( hasattr(pykd, 'dprint') )
self.assertTrue( hasattr(pykd, 'dprintln') ) self.assertTrue( hasattr(pykd, 'dprintln') )
@ -101,12 +100,12 @@ class BaseTest( unittest.TestCase ):
self.assertTrue( hasattr(pykd, 'intBase') ) self.assertTrue( hasattr(pykd, 'intBase') )
self.assertTrue( hasattr(pykd, 'typeInfo') ) self.assertTrue( hasattr(pykd, 'typeInfo') )
self.assertTrue( hasattr(pykd, 'typedVar') ) self.assertTrue( hasattr(pykd, 'typedVar') )
self.assertTrue( hasattr(pykd, 'windbgIn') )
self.assertTrue( hasattr(pykd, 'windbgOut') )
def testOldRemovedApi( self ): def testOldRemovedApi( self ):
""" Branch test: old API 0.0.x what should be removed """ """ Branch test: old API 0.0.x what should be removed """
self.assertFalse( hasattr(pykd, 'dbgModuleClass') ) self.assertFalse( hasattr(pykd, 'dbgModuleClass') )
self.assertFalse( hasattr(pykd, 'windbgIn') )
self.assertFalse( hasattr(pykd, 'windbgOut') )
def testNewAddededApi( self ): def testNewAddededApi( self ):
""" Branch test: new API 0.1.x what must be available """ """ Branch test: new API 0.1.x what must be available """

10
test/scripts/dbgcmd.py Normal file
View File

@ -0,0 +1,10 @@
import unittest
import target
import pykd
class DbgcmdTest( unittest.TestCase ):
def testDbgCommand( self ):
self.assertNotEqual( "", pykd.dbgCommand("lm") )

View File

@ -16,6 +16,7 @@ import typeinfo
import regtest import regtest
import moduletest import moduletest
import diatest import diatest
import dbgcmd
def getTestSuite( singleName = "" ): def getTestSuite( singleName = "" ):
if singleName == "": if singleName == "":
@ -24,7 +25,7 @@ def getTestSuite( singleName = "" ):
unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ), unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ),
unittest.TestLoader().loadTestsFromTestCase( diatest.DiaTest ), unittest.TestLoader().loadTestsFromTestCase( diatest.DiaTest ),
unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
# unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ) unittest.TestLoader().loadTestsFromTestCase( dbgcmd.DbgcmdTest )
] ) ] )
else: else:
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) ) return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )

View File

@ -404,6 +404,10 @@
RelativePath="..\scripts\basetest.py" RelativePath="..\scripts\basetest.py"
> >
</File> </File>
<File
RelativePath="..\scripts\dbgcmd.py"
>
</File>
<File <File
RelativePath="..\scripts\diatest.py" RelativePath="..\scripts\diatest.py"
> >