[0.1.x] added : print, eprint, dprintln, eprintln

git-svn-id: https://pykd.svn.codeplex.com/svn@70179 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-10-03 11:34:36 +00:00 committed by Mikhail I. Izmestev
parent b86f25f88e
commit 804dc17443
7 changed files with 492 additions and 317 deletions

View File

@ -57,6 +57,14 @@ public:
ULONG64 addr64( ULONG64 addr ); ULONG64 addr64( ULONG64 addr );
void dprint( const std::string &str, bool dml = false );
void dprintln( const std::string &str, bool dml = false );
void eprint( const std::string &str );
void eprintln( const std::string &str );
private: private:
DebugClient(); DebugClient();

View File

@ -4,9 +4,11 @@
#include <dia2.h> #include <dia2.h>
#include "windbg.h"
#include "module.h" #include "module.h"
#include "diawrapper.h" #include "diawrapper.h"
#include "dbgclient.h" #include "dbgclient.h"
#include "dbgio.h"
using namespace pykd; using namespace pykd;
@ -60,22 +62,32 @@ BOOST_PYTHON_MODULE( pykd )
.def( "loadModule", &pykd::DebugClient::loadModule, .def( "loadModule", &pykd::DebugClient::loadModule,
"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( "dprint", &pykd::DebugClient::dprint,
"Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" )
.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, // python::def( "createDbgClient", pykd::DebugClient::createDbgClient,
// "create a new instance of the dbgClient class" ); // "create a new instance of the dbgClient class" );
python::def( "loadDump", &loadDump, python::def( "loadDump", &pykd::loadDump,
"Load crash dump (only for console)"); "Load crash dump (only for console)");
python::def( "startProcess", &startProcess, python::def( "startProcess", &pykd::startProcess,
"Start process for debugging (only for console)"); "Start process for debugging (only for console)");
python::def( "attachProcess", &attachProcess, python::def( "attachProcess", &pykd::attachProcess,
"Attach debugger to a exsisting process" ); "Attach debugger to a exsisting process" );
python::def( "attachKernel", &attachKernel, python::def( "attachKernel", &pykd::attachKernel,
"Attach debugger to a kernel target" ); "Attach debugger to a kernel target" );
python::def( "loadModule", &loadModule, python::def( "loadModule", &pykd::loadModule,
"Return instance of Module class" ); "Return instance of Module class" );
python::def( "findModule", &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( "dprint", &pykd::dprint,
"Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" );
python::def( "dprintln", &pykd::dprintln,
"Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" );
python::class_<pykd::TypeInfo>("typeInfo", "Class representing typeInfo", python::no_init ); python::class_<pykd::TypeInfo>("typeInfo", "Class representing typeInfo", python::no_init );
@ -297,80 +309,33 @@ BOOST_PYTHON_MODULE( pykd )
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class WindbgGlobalSession WindbgGlobalSession::WindbgGlobalSession() {
{
public:
static PyImport_AppendInittab("pykd", initpykd );
boost::python::object
global() { PyEval_InitThreads();
return windbgGlobalSession->main.attr("__dict__");
Py_Initialize();
main = boost::python::import("__main__");
python::object main_namespace = main.attr("__dict__");
// äåëàåì àíàëîã from pykd import *
python::object pykd = boost::python::import( "pykd" );
python::dict pykd_namespace( pykd.attr("__dict__") );
python::list iterkeys( pykd_namespace.iterkeys() );
for (int i = 0; i < boost::python::len(iterkeys); i++)
{
std::string key = boost::python::extract<std::string>(iterkeys[i]);
main_namespace[ key ] = pykd_namespace[ key ];
} }
}
static
VOID
StartWindbgSession() {
if ( 1 == InterlockedIncrement( &sessionCount ) )
{
windbgGlobalSession = new WindbgGlobalSession();
}
}
static
VOID
StopWindbgSession() {
if ( 0 == InterlockedDecrement( &sessionCount ) )
{
delete windbgGlobalSession;
windbgGlobalSession = NULL;
}
}
static
bool isInit() {
return windbgGlobalSession != NULL;
}
private:
WindbgGlobalSession() {
PyImport_AppendInittab("pykd", initpykd );
PyEval_InitThreads();
Py_Initialize();
main = boost::python::import("__main__");
python::object main_namespace = main.attr("__dict__");
// äåëàåì àíàëîã from pykd import *
python::object pykd = boost::python::import( "pykd" );
python::dict pykd_namespace( pykd.attr("__dict__") );
python::list iterkeys( pykd_namespace.iterkeys() );
for (int i = 0; i < boost::python::len(iterkeys); i++)
{
std::string key = boost::python::extract<std::string>(iterkeys[i]);
main_namespace[ key ] = pykd_namespace[ key ];
}
}
~WindbgGlobalSession() {
}
python::object main;
static volatile LONG sessionCount;
static WindbgGlobalSession *windbgGlobalSession;
};
volatile LONG WindbgGlobalSession::sessionCount = 0; volatile LONG WindbgGlobalSession::sessionCount = 0;
@ -419,7 +384,7 @@ py( PDEBUG_CLIENT4 client, PCSTR args )
} }
catch(...) catch(...)
{ {
// dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "unexpected error" ); dbgClient->eprintln( "unexpected error" );
} }
Py_EndInterpreter( localInterpreter ); Py_EndInterpreter( localInterpreter );
@ -436,6 +401,22 @@ HRESULT
CALLBACK CALLBACK
pycmd( PDEBUG_CLIENT4 client, PCSTR args ) pycmd( PDEBUG_CLIENT4 client, PCSTR args )
{ {
DebugClientPtr dbgClient = DebugClient::createDbgClient( client );
DebugClientPtr oldClient = DebugClient::setDbgClientCurrent( dbgClient );
try {
}
catch(...)
{
dbgClient->eprintln( "unexpected error" );
}
DebugClient::setDbgClientCurrent( oldClient );
return S_OK;
return S_OK; return S_OK;
} }

View File

@ -1,59 +1,158 @@
#include "stdafx.h" #include "stdafx.h"
#include <iostream> #include <iostream>
#include <Fcntl.h>
#include "dbgio.h" #include "dbgio.h"
#include "dbgext.h" #include "dbgclient.h"
#include "windbg.h"
using namespace std; namespace pykd {
///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
void dbgPrint::dprint( const boost::python::object& obj, bool dml ) void DebugClient::dprint( const std::string &str, bool dml )
{ {
std::wstring str = boost::python::extract<std::wstring>( obj ); if ( WindbgGlobalSession::isInit() )
if ( isWindbgExt() )
{ {
for ( size_t i = 0; i < str.size() / 100 + 1; ++i ) for ( size_t i = 0; i < str.size() / 100 + 1; ++i )
{ {
dbgExt->control4->ControlledOutputWide( m_control->ControlledOutputWide(
dml ? DEBUG_OUTCTL_AMBIENT_DML : DEBUG_OUTCTL_AMBIENT_TEXT, DEBUG_OUTPUT_NORMAL, dml ? DEBUG_OUTCTL_AMBIENT_DML : DEBUG_OUTCTL_AMBIENT_TEXT, DEBUG_OUTPUT_NORMAL,
L"%ws", L"%s",
str.substr( i*100, min( str.size() - i*100, 100 ) ).c_str() str.substr( i*100, min( str.size() - i*100, 100 ) ).c_str()
); );
} }
} }
else else
{ {
std::wcout << str; std::cout << str;
} }
} }
///////////////////////////////////////////////////////////////////////////////// void dprint( const std::string &str, bool dml )
void dbgPrint::dprintln( const boost::python::object& obj, bool dml )
{ {
std::wstring str = boost::python::extract<std::wstring>( obj ); g_dbgClient->dprint( str, dml );
str += L"\r\n"; }
if ( isWindbgExt() )
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::dprintln( const std::string &str, bool dml )
{
this->dprint( str + "\r\n", dml );
}
void dprintln( const std::string &str, bool dml )
{
g_dbgClient->dprintln( str, dml );
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::eprint( const std::string &str )
{
if ( WindbgGlobalSession::isInit() )
{ {
for ( size_t i = 0; i < str.size() / 100 + 1; ++i ) for ( size_t i = 0; i < str.size() / 100 + 1; ++i )
{ {
dbgExt->control4->ControlledOutputWide( m_control->OutputWide(
dml ? DEBUG_OUTCTL_AMBIENT_DML : DEBUG_OUTCTL_AMBIENT_TEXT, DEBUG_OUTPUT_NORMAL, DEBUG_OUTPUT_ERROR,
L"%ws", L"%s",
str.substr( i*100, min( str.size() - i*100, 100 ) ).c_str() str.substr( i*100, min( str.size() - i*100, 100 ) ).c_str()
); );
} }
} }
else else
{ {
std::wcout << str; std::cerr << str;
} }
} }
///////////////////////////////////////////////////////////////////////////////// void eprint( const std::string &str )
{
g_dbgClient->eprint( str );
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::eprintln( const std::string &str )
{
this->eprint( str + "\r\n");
}
void eprintln( const std::string &str )
{
g_dbgClient->eprintln( str );
}
///////////////////////////////////////////////////////////////////////////////////
}; // namesapce pykd
//
//void dbgPrint::dprint( const boost::python::object& obj, bool dml )
//{
// std::wstring str = boost::python::extract<std::wstring>( obj );
//
// if ( isWindbgExt() )
// {
//
// for ( size_t i = 0; i < str.size() / 100 + 1; ++i )
// {
// dbgExt->control4->ControlledOutputWide(
// dml ? DEBUG_OUTCTL_AMBIENT_DML : DEBUG_OUTCTL_AMBIENT_TEXT, DEBUG_OUTPUT_NORMAL,
// L"%ws",
// str.substr( i*100, min( str.size() - i*100, 100 ) ).c_str()
// );
// }
// }
// else
// {
// std::wcout << str;
// }
//}
//
///////////////////////////////////////////////////////////////////////////////////
//
//void dbgPrint::dprintln( const boost::python::object& obj, bool dml )
//{
// std::wstring str = boost::python::extract<std::wstring>( obj );
// str += L"\r\n";
//
// if ( isWindbgExt() )
// {
// for ( size_t i = 0; i < str.size() / 100 + 1; ++i )
// {
// dbgExt->control4->ControlledOutputWide(
// dml ? DEBUG_OUTCTL_AMBIENT_DML : DEBUG_OUTCTL_AMBIENT_TEXT, DEBUG_OUTPUT_NORMAL,
// L"%ws",
// str.substr( i*100, min( str.size() - i*100, 100 ) ).c_str()
// );
// }
// }
// else
// {
// std::wcout << str;
// }
//}
//
///////////////////////////////////////////////////////////////////////////////////

View File

@ -1,224 +1,238 @@
#pragma once #pragma once
#include <string>
#include <dbgeng.h>
#include "dbgext.h" namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
void dprint( const std::string &str, bool dml = false );
void dprintln( const std::string &str, bool dml = false );
void eprint( const std::string &str );
void eprintln( const std::string &str );
///////////////////////////////////////////////////////////////////////////////////
};
//
//class dbgPrint {
//
//public:
//
// static void dprint( const boost::python::object& obj, bool dml = false );
//
// static void dprintln( const boost::python::object& obj, bool dml = false );
//
//};
//
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
//
class dbgPrint { //// êëàññ äëÿ ïåðåõâàòà âûâîäà â îòëàä÷èê
//
public: //class OutputReader : public IDebugOutputCallbacks {
//
static void dprint( const boost::python::object& obj, bool dml = false ); //public:
//
static void dprintln( const boost::python::object& obj, bool dml = false ); // OutputReader( IDebugClient *debugClient )
// {
}; // HRESULT hres;
//
/////////////////////////////////////////////////////////////////////////////// // try {
//
// êëàññ äëÿ ïåðåõâàòà âûâîäà â îòëàä÷èê // m_debugClient = debugClient;
// m_debugClient->AddRef();
class OutputReader : public IDebugOutputCallbacks { //
// hres = m_debugClient->GetOutputCallbacks( &m_previousCallback );
public: // if ( FAILED( hres ) )
// {
OutputReader( IDebugClient *debugClient ) // throw hres;
{ // }
HRESULT hres; //
// hres = m_debugClient->SetOutputCallbacks( this );
try { // if ( FAILED( hres ) )
// {
m_debugClient = debugClient; // throw hres;
m_debugClient->AddRef(); // }
//
hres = m_debugClient->GetOutputCallbacks( &m_previousCallback ); // } catch( ... )
if ( FAILED( hres ) ) // {
{ // m_debugClient->Release();
throw hres; // m_debugClient = NULL;
} // }
// }
hres = m_debugClient->SetOutputCallbacks( this ); //
if ( FAILED( hres ) ) // ~OutputReader()
{ // {
throw hres; // if ( m_debugClient )
} // {
// m_debugClient->SetOutputCallbacks( m_previousCallback );
} catch( ... ) // m_debugClient->Release();
{ // }
m_debugClient->Release(); // }
m_debugClient = NULL; //
} // const std::string&
} // Line() const {
// return m_readLine;
~OutputReader() // }
{ //
if ( m_debugClient ) //private:
{ //
m_debugClient->SetOutputCallbacks( m_previousCallback ); // // IUnknown.
m_debugClient->Release(); // STDMETHOD(QueryInterface)(
} // __in REFIID InterfaceId,
} // __out PVOID* Interface ) {
// return E_NOINTERFACE;
const std::string& // }
Line() const { //
return m_readLine; // STDMETHOD_(ULONG, AddRef)() {
} // return 1L;
// }
private: //
//
// IUnknown. // STDMETHOD_(ULONG, Release)() {
STDMETHOD(QueryInterface)( // return 0L;
__in REFIID InterfaceId, // }
__out PVOID* Interface ) { //
return E_NOINTERFACE; // STDMETHOD(Output)(
} // __in ULONG Mask,
// __in PCSTR Text )
STDMETHOD_(ULONG, AddRef)() { // {
return 1L; // if ( Mask == DEBUG_OUTPUT_NORMAL )
} // {
// m_readLine += std::string( Text );
// }
STDMETHOD_(ULONG, Release)() { //
return 0L; // return S_OK;
} // }
//
STDMETHOD(Output)( //private:
__in ULONG Mask, //
__in PCSTR Text ) // std::string m_readLine;
{ //
if ( Mask == DEBUG_OUTPUT_NORMAL ) // IDebugClient *m_debugClient;
{ //
m_readLine += std::string( Text ); // IDebugOutputCallbacks *m_previousCallback;
} //};
//
return S_OK;
}
private:
std::string m_readLine;
IDebugClient *m_debugClient;
IDebugOutputCallbacks *m_previousCallback;
};
///////////////////////////////////////////////////////////////////////////////
class InputReader : public IDebugInputCallbacks {
public:
InputReader( IDebugClient *debugClient )
{
HRESULT hres;
try {
m_debugClient = debugClient;
m_debugClient->AddRef();
hres = m_debugClient->GetInputCallbacks( &m_previousCallback );
if ( FAILED( hres ) )
{
throw hres;
}
hres = m_debugClient->SetInputCallbacks( this );
if ( FAILED( hres ) )
{
throw hres;
}
} catch( ... )
{
m_debugClient->Release();
m_debugClient = NULL;
}
}
~InputReader()
{
if ( m_debugClient )
{
m_debugClient->SetInputCallbacks( m_previousCallback );
m_debugClient->Release();
}
}
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 ) {
return S_OK;
}
private:
IDebugClient *m_debugClient;
IDebugInputCallbacks *m_previousCallback;
};
/////////////////////////////////////////////////////////////////////////////////
class dbgOut {
public:
void
write( const boost::python::object &str ) {
dbgPrint::dprint( str );
}
};
/////////////////////////////////////////////////////////////////////////////////
class dbgIn {
public:
std::string
readline() {
char str[100];
ULONG inputSize;
OutputReader outputReader( dbgExt->client );
dbgExt->control->Input( str, sizeof(str), &inputSize );
return std::string( str );
}
};
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
//
//class InputReader : public IDebugInputCallbacks {
//
//public:
//
// InputReader( IDebugClient *debugClient )
// {
// HRESULT hres;
//
// try {
//
// m_debugClient = debugClient;
// m_debugClient->AddRef();
//
// hres = m_debugClient->GetInputCallbacks( &m_previousCallback );
// if ( FAILED( hres ) )
// {
// throw hres;
// }
//
// hres = m_debugClient->SetInputCallbacks( this );
// if ( FAILED( hres ) )
// {
// throw hres;
// }
//
// } catch( ... )
// {
// m_debugClient->Release();
// m_debugClient = NULL;
// }
// }
//
// ~InputReader()
// {
// if ( m_debugClient )
// {
// m_debugClient->SetInputCallbacks( m_previousCallback );
// m_debugClient->Release();
// }
// }
//
//
//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 ) {
// return S_OK;
// }
//
//private:
//
// IDebugClient *m_debugClient;
//
// IDebugInputCallbacks *m_previousCallback;
//
//};
//
//
///////////////////////////////////////////////////////////////////////////////////
//
//class dbgOut {
//
//public:
//
// void
// write( const boost::python::object &str ) {
// dbgPrint::dprint( str );
// }
//
//};
//
///////////////////////////////////////////////////////////////////////////////////
//
//class dbgIn {
//
//public:
//
// std::string
// readline() {
//
// char str[100];
// ULONG inputSize;
//
// OutputReader outputReader( dbgExt->client );
//
// dbgExt->control->Input( str, sizeof(str), &inputSize );
//
// return std::string( str );
// }
//
//};
//
///////////////////////////////////////////////////////////////////////////////////

View File

@ -361,6 +361,10 @@
RelativePath=".\dbgext.cpp" RelativePath=".\dbgext.cpp"
> >
</File> </File>
<File
RelativePath=".\dbgio.cpp"
>
</File>
<File <File
RelativePath=".\dbgmem.cpp" RelativePath=".\dbgmem.cpp"
> >
@ -435,6 +439,10 @@
RelativePath=".\dbgexcept.h" RelativePath=".\dbgexcept.h"
> >
</File> </File>
<File
RelativePath=".\dbgio.h"
>
</File>
<File <File
RelativePath=".\dbgmem.h" RelativePath=".\dbgmem.h"
> >
@ -475,6 +483,10 @@
RelativePath=".\utils.h" RelativePath=".\utils.h"
> >
</File> </File>
<File
RelativePath=".\windbg.h"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Resource Files" Name="Resource Files"

62
pykd/windbg.h Normal file
View File

@ -0,0 +1,62 @@
#pragma once
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
class WindbgGlobalSession
{
public:
static
boost::python::object
global() {
return windbgGlobalSession->main.attr("__dict__");
}
static
VOID
StartWindbgSession() {
if ( 1 == InterlockedIncrement( &sessionCount ) )
{
windbgGlobalSession = new WindbgGlobalSession();
}
}
static
VOID
StopWindbgSession() {
if ( 0 == InterlockedDecrement( &sessionCount ) )
{
delete windbgGlobalSession;
windbgGlobalSession = NULL;
}
}
static
bool isInit() {
return windbgGlobalSession != NULL;
}
private:
WindbgGlobalSession();
~WindbgGlobalSession() {
}
python::object main;
static volatile LONG sessionCount;
static WindbgGlobalSession *windbgGlobalSession;
};
///////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd

View File

@ -12,4 +12,3 @@ class BaseTest( unittest.TestCase ):
self.assertNotEqual( None, pykd.module ) self.assertNotEqual( None, pykd.module )
self.assertNotEqual( None, pykd.dbgClient ) self.assertNotEqual( None, pykd.dbgClient )
# self.assertNotEqual( None, pykd.dia )