mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[0.1.x] added : !pycmd implementation
git-svn-id: https://pykd.svn.codeplex.com/svn@70280 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
f33a030f84
commit
5ef445611c
@ -8,7 +8,7 @@ namespace pykd {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DebugClientPtr g_dbgClient( DebugClient::createDbgClient() );
|
||||
DebugClientPtr g_dbgClient; //( DebugClient::createDbgClient() );
|
||||
|
||||
void loadDump( const std::wstring &fileName ) {
|
||||
g_dbgClient->loadDump( fileName );
|
||||
@ -37,43 +37,6 @@ DebugClientPtr DebugClient::setDbgClientCurrent( DebugClientPtr newDbgClient )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DebugClient::DebugClient()
|
||||
{
|
||||
HRESULT hres;
|
||||
hres = DebugCreate( __uuidof(IDebugClient5), (void **)&m_client );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException("DebugCreate failed");
|
||||
|
||||
hres = m_client->QueryInterface( __uuidof(IDebugControl4), (void**)&m_control );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException("QueryInterface IDebugControl4 failed");
|
||||
|
||||
hres = m_client->QueryInterface( __uuidof(IDebugSymbols3), (void**)&m_symbols );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException("QueryInterface IDebugSymbols3 failed");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DebugClient::DebugClient( IDebugClient4 *client )
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
hres = client->QueryInterface( __uuidof(IDebugClient5), (void**)&m_client );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException("QueryInterface IDebugControl4 failed");
|
||||
|
||||
hres = client->QueryInterface( __uuidof(IDebugControl4), (void**)&m_control );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException("QueryInterface IDebugControl4 failed");
|
||||
|
||||
hres = client->QueryInterface( __uuidof(IDebugSymbols3), (void**)&m_symbols );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException("QueryInterface IDebugSymbols3 failed");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DebugClient::loadDump( const std::wstring &fileName )
|
||||
{
|
||||
HRESULT hres;
|
||||
@ -133,7 +96,7 @@ void DebugClient::attachKernel( const std::wstring ¶m )
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
hres = m_client->AttachKernelWide( DEBUG_ATTACH_KERNEL_CONNECTION, param.c_str() );
|
||||
hres = m_client5->AttachKernelWide( DEBUG_ATTACH_KERNEL_CONNECTION, param.c_str() );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugClient5::AttachKernelWide failed" );
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <boost\smart_ptr\scoped_ptr.hpp>
|
||||
|
||||
#include "dbgobj.h"
|
||||
#include "dbgexcept.h"
|
||||
#include "module.h"
|
||||
#include "dbgio.h"
|
||||
@ -21,7 +22,7 @@ typedef boost::shared_ptr<DebugClient> DebugClientPtr;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class DebugClient {
|
||||
class DebugClient : private DbgObject {
|
||||
|
||||
public:
|
||||
|
||||
@ -29,7 +30,15 @@ public:
|
||||
|
||||
static
|
||||
DebugClientPtr createDbgClient() {
|
||||
return DebugClientPtr( new DebugClient() );
|
||||
|
||||
HRESULT hres;
|
||||
CComPtr<IDebugClient4> client = NULL;
|
||||
|
||||
hres = DebugCreate( __uuidof(IDebugClient4), (void **)&client );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException("DebugCreate failed");
|
||||
|
||||
return createDbgClient( client );
|
||||
}
|
||||
|
||||
static
|
||||
@ -74,15 +83,26 @@ public:
|
||||
return DbgIn( m_client );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
CComPtr<IDebugClient4>&
|
||||
client() {
|
||||
return m_client;
|
||||
}
|
||||
|
||||
CComPtr<IDebugClient5>&
|
||||
client5() {
|
||||
return m_client5;
|
||||
}
|
||||
|
||||
CComPtr<IDebugControl4>&
|
||||
control() {
|
||||
return m_control;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
DebugClient();
|
||||
|
||||
DebugClient( IDebugClient4 *client );
|
||||
|
||||
CComPtr<IDebugClient5> m_client;
|
||||
CComPtr<IDebugControl4> m_control;
|
||||
CComPtr<IDebugSymbols3> m_symbols;
|
||||
DebugClient( IDebugClient4 *client ) : DbgObject( client ) {}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -73,8 +73,8 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
.def( "dprintln", &pykd::DebugClient::dprintln,
|
||||
"Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" );
|
||||
|
||||
// python::def( "createDbgClient", pykd::DebugClient::createDbgClient,
|
||||
// "create a new instance of the dbgClient class" );
|
||||
python::def( "createDbgClient", (DebugClientPtr(*)())&pykd::DebugClient::createDbgClient,
|
||||
"create a new instance of the dbgClient class" );
|
||||
python::def( "loadDump", &pykd::loadDump,
|
||||
"Load crash dump (only for console)");
|
||||
python::def( "startProcess", &pykd::startProcess,
|
||||
@ -392,15 +392,13 @@ py( PDEBUG_CLIENT4 client, PCSTR args )
|
||||
try {
|
||||
|
||||
// ïîëó÷àåì äîñòïó ê ãëîáàëüíîìó ìàïó ( íóæåí äëÿ âûçîâà exec_file )
|
||||
boost::python::object main = python::import("__main__");
|
||||
python::object main = python::import("__main__");
|
||||
|
||||
boost::python::object global(main.attr("__dict__"));
|
||||
python::object global(main.attr("__dict__"));
|
||||
|
||||
boost::python::import( "pykd" );
|
||||
|
||||
// íàñòðàèâàåì ââîä/âûâîä ( ÷òîáû â ñêðèïòå ìîæíî áûëî ïèñàòü print )
|
||||
|
||||
boost::python::object sys = boost::python::import("sys");
|
||||
python::object sys = python::import("sys");
|
||||
|
||||
sys.attr("stdout") = python::object( dbgClient->dout() );
|
||||
sys.attr("stdin") = python::object( dbgClient->din() );
|
||||
@ -514,7 +512,21 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args )
|
||||
|
||||
try {
|
||||
|
||||
|
||||
// ïåðåíàïðàâëåíèå ñòàíäàðòíûõ ïîòîêîâ ÂÂ
|
||||
python::object sys = python::import("sys");
|
||||
|
||||
sys.attr("stdout") = python::object( DbgOut( client ) );
|
||||
sys.attr("stdin") = python::object( DbgIn( client ) );
|
||||
|
||||
client->SetOutputMask( DEBUG_OUTPUT_NORMAL );
|
||||
//client->SetInputCallbacks( NULL );
|
||||
|
||||
PyRun_String(
|
||||
"__import__('code').InteractiveConsole(__import__('__main__').__dict__).interact()",
|
||||
Py_file_input,
|
||||
WindbgGlobalSession::global().ptr(),
|
||||
WindbgGlobalSession::global().ptr()
|
||||
);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@ -94,8 +94,9 @@ DbgOut::write( const std::wstring &str )
|
||||
{
|
||||
for ( size_t i = 0; i < str.size() / 100 + 1; ++i )
|
||||
{
|
||||
m_control->OutputWide(
|
||||
DEBUG_OUTPUT_ERROR,
|
||||
m_control->ControlledOutputWide(
|
||||
DEBUG_OUTCTL_AMBIENT_TEXT,
|
||||
DEBUG_OUTPUT_NORMAL,
|
||||
L"%ws",
|
||||
str.substr( i*100, min( str.size() - i*100, 100 ) ).c_str()
|
||||
);
|
||||
@ -112,7 +113,12 @@ DbgOut::write( const std::wstring &str )
|
||||
std::string
|
||||
DbgIn::readline()
|
||||
{
|
||||
return "";
|
||||
char str[0x100];
|
||||
ULONG inputSize = 0;
|
||||
|
||||
m_control->Input( str, sizeof(str), &inputSize );
|
||||
|
||||
return std::string( str ) + "\n";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
143
pykd/dbgio.h
143
pykd/dbgio.h
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "dbgobj.h"
|
||||
#include <vector>
|
||||
|
||||
namespace pykd {
|
||||
|
||||
@ -20,7 +21,7 @@ class DbgOut : private DbgObject {
|
||||
|
||||
public:
|
||||
|
||||
DbgOut( IDebugClient5 *client ) : DbgObject( client )
|
||||
DbgOut( IDebugClient4 *client ) : DbgObject( client )
|
||||
{}
|
||||
|
||||
void
|
||||
@ -33,7 +34,7 @@ class DbgIn : private DbgObject {
|
||||
|
||||
public:
|
||||
|
||||
DbgIn( IDebugClient5 *client ) : DbgObject( client )
|
||||
DbgIn( IDebugClient4 *client ) : DbgObject( client )
|
||||
{}
|
||||
|
||||
std::string
|
||||
@ -42,4 +43,142 @@ public:
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// êëàññ äëÿ ïåðåõâàòà âûâîäà â îòëàä÷èê
|
||||
|
||||
class OutputReader : private DbgObject, public IDebugOutputCallbacks, private boost::noncopyable {
|
||||
|
||||
public:
|
||||
|
||||
explicit OutputReader( IDebugClient4 *client ) : DbgObject( client )
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
hres = m_client->GetOutputCallbacks( &m_previousCallback );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugClient::GetOutputCallbacks failed" );
|
||||
|
||||
hres = m_client->SetOutputCallbacks( this );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugClient::GetOutputCallbacks failed" );
|
||||
|
||||
}
|
||||
|
||||
~OutputReader()
|
||||
{
|
||||
if ( m_previousCallback )
|
||||
m_client->SetOutputCallbacks( m_previousCallback );
|
||||
}
|
||||
|
||||
const std::string&
|
||||
Line() const {
|
||||
return m_readLine;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// IUnknown.
|
||||
STDMETHOD(QueryInterface)(
|
||||
__in REFIID InterfaceId,
|
||||
__out PVOID* Interface ) {
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
STDMETHOD_(ULONG, AddRef)() {
|
||||
return 1L;
|
||||
}
|
||||
|
||||
|
||||
STDMETHOD_(ULONG, Release)() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
STDMETHOD(Output)(
|
||||
__in ULONG Mask,
|
||||
__in PCSTR Text )
|
||||
{
|
||||
if ( Mask == DEBUG_OUTPUT_NORMAL )
|
||||
{
|
||||
m_readLine += std::string( Text );
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::string m_readLine;
|
||||
|
||||
CComPtr<IDebugOutputCallbacks> m_previousCallback;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//class InputReader : public IDebugInputCallbacks, private DbgObject, private boost::noncopyable {
|
||||
//
|
||||
//public:
|
||||
//
|
||||
// explicit InputReader( IDebugClient4 *debugClient ) : DbgObject( debugClient )
|
||||
// {
|
||||
// HRESULT hres;
|
||||
//
|
||||
// hres = m_client->GetInputCallbacks( &m_previousCallback );
|
||||
// if ( FAILED( hres ) )
|
||||
// throw DbgException( "IDebugClient::GetInputCallbacks failed" );
|
||||
//
|
||||
// hres = m_client->SetInputCallbacks( this );
|
||||
// if ( FAILED( hres ) )
|
||||
// throw DbgException( "IDebugClient::SetInputCallbacks failed" );
|
||||
// }
|
||||
//
|
||||
// ~InputReader()
|
||||
// {
|
||||
// if ( m_previousCallback )
|
||||
// m_client->SetInputCallbacks( m_previousCallback );
|
||||
// }
|
||||
//
|
||||
//
|
||||
//private:
|
||||
//
|
||||
// // IUnknown.
|
||||
// STDMETHOD(QueryInterface)(
|
||||
// __in REFIID InterfaceId,
|
||||
// __out PVOID* Interface ) {
|
||||
// return E_NOINTERFACE;
|
||||
// }
|
||||
//
|
||||
// STDMETHOD_(ULONG, AddRef)() {
|
||||
// return 1L;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// STDMETHOD_(ULONG, Release)() {
|
||||
// return 0L;
|
||||
// }
|
||||
//
|
||||
// STDMETHOD( EndInput )() {
|
||||
// return S_OK;
|
||||
// }
|
||||
//
|
||||
// STDMETHOD( StartInput )(
|
||||
// IN ULONG BufferSize ) {
|
||||
//
|
||||
// std::vector<char> buf(BufferSize);
|
||||
//
|
||||
// ULONG inputSize;
|
||||
//
|
||||
// m_control->Input( &buf[0], BufferSize, &inputSize );
|
||||
//
|
||||
// m_control->ReturnInput( &buf[0] );
|
||||
//
|
||||
// return S_OK;
|
||||
// }
|
||||
//
|
||||
//private:
|
||||
//
|
||||
// CComPtr<IDebugInputCallbacks> m_previousCallback;
|
||||
//
|
||||
//};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
};
|
@ -11,12 +11,14 @@ class DbgObject {
|
||||
|
||||
protected:
|
||||
|
||||
DbgObject( IDebugClient5 *client ) {
|
||||
DbgObject( IDebugClient4 *client ) {
|
||||
|
||||
m_client = client;
|
||||
|
||||
HRESULT hres;
|
||||
hres = client->QueryInterface( __uuidof(IDebugClient5), (void **)&m_client );
|
||||
hres = client->QueryInterface( __uuidof(IDebugClient5), (void **)&m_client5 );
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException("DebugCreate failed");
|
||||
throw DbgException("QueryInterface IDebugClient5 failed");
|
||||
|
||||
hres = client->QueryInterface( __uuidof(IDebugControl4), (void**)&m_control );
|
||||
if ( FAILED( hres ) )
|
||||
@ -33,7 +35,8 @@ protected:
|
||||
|
||||
virtual ~DbgObject() {};
|
||||
|
||||
CComPtr<IDebugClient5> m_client;
|
||||
CComPtr<IDebugClient5> m_client5;
|
||||
CComPtr<IDebugClient4> m_client;
|
||||
CComPtr<IDebugControl4> m_control;
|
||||
CComPtr<IDebugSymbols3> m_symbols;
|
||||
CComPtr<IDebugAdvanced2> m_advanced;
|
||||
|
@ -20,7 +20,7 @@ Module findModule( ULONG64 offset ) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module::Module( IDebugClient5 *client, const std::string& moduleName ) : DbgObject( client )
|
||||
Module::Module( IDebugClient4 *client, const std::string& moduleName ) : DbgObject( client )
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
@ -55,7 +55,7 @@ Module::Module( IDebugClient5 *client, const std::string& moduleName ) : DbgObje
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module::Module( IDebugClient5 *client, ULONG64 offset ) : DbgObject( client )
|
||||
Module::Module( IDebugClient4 *client, ULONG64 offset ) : DbgObject( client )
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -14,9 +14,9 @@ class Module : private DbgObject {
|
||||
|
||||
public:
|
||||
|
||||
Module( IDebugClient5 *client, const std::string& moduleName );
|
||||
Module( IDebugClient4 *client, const std::string& moduleName );
|
||||
|
||||
Module( IDebugClient5 *client, ULONG64 offset );
|
||||
Module( IDebugClient4 *client, ULONG64 offset );
|
||||
|
||||
std::string getName() {
|
||||
return m_name;
|
||||
|
Loading…
Reference in New Issue
Block a user