[0.1.x] added : dbgClient class

git-svn-id: https://pykd.svn.codeplex.com/svn@69780 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-09-15 14:16:20 +00:00 committed by Mikhail I. Izmestev
parent 7329a9f7bc
commit ea4a18f54b
13 changed files with 275 additions and 24 deletions

88
pykd/dbgclient.cpp Normal file
View File

@ -0,0 +1,88 @@
#include "stdafx.h"
#include "dbgclient.h"
#include <vector>
using namespace pykd;
///////////////////////////////////////////////////////////////////////////////////
DebugClient::DebugClient()
{
HRESULT hres;
hres = DebugCreate( __uuidof(IDebugClient4), (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");
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::loadDump( const std::wstring &fileName )
{
HRESULT hres;
hres = m_client->OpenDumpFileWide( fileName.c_str(), NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugClient4::OpenDumpFileWide failed" );
hres = m_control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::WaitForEvent failed" );
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::startProcess( const std::wstring &processName )
{
HRESULT hres;
ULONG opt;
hres = m_control->GetEngineOptions( &opt );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetEngineOptions failed" );
opt |= DEBUG_ENGOPT_INITIAL_BREAK;
hres = m_control->SetEngineOptions( opt );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::SetEngineOptions failed" );
std::vector< std::wstring::value_type> cmdLine( processName.size() + 1 );
wcscpy_s( &cmdLine[0], cmdLine.size(), processName.c_str() );
hres = m_client->CreateProcessWide( 0, &cmdLine[0], DEBUG_PROCESS | DETACHED_PROCESS );
if ( FAILED( hres ) )
throw DbgException( "IDebugClient4::CreateProcessWide failed" );
hres = m_control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::WaitForEvent failed" );
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::attachProcess( ULONG processId )
{
HRESULT hres;
hres = m_client->AttachProcess( 0, processId, 0 );
if ( FAILED( hres ) )
throw DbgException( "IDebugClient::AttachProcess failed" );
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::attachKernel( const std::wstring &param )
{
HRESULT hres;
hres = m_client->AttachKernelWide( DEBUG_ATTACH_KERNEL_CONNECTION, param.c_str() );
if ( FAILED( hres ) )
throw DbgException( "IDebugClient5::AttachKernelWide failed" );
}
///////////////////////////////////////////////////////////////////////////////////

View File

@ -1,5 +1,52 @@
#pragma once
#include <string>
#include <dbgeng.h>
#include <dbghelp.h>
#include "dbgexcept.h"
/////////////////////////////////////////////////////////////////////////////////
namespace pykd {
/////////////////////////////////////////////////////////////////////////////////
class DebugClient {
public:
DebugClient();
virtual ~DebugClient() {}
void loadDump( const std::wstring &fileName );
void startProcess( const std::wstring &processName );
void attachProcess( ULONG processId );
void attachKernel( const std::wstring &param );
private:
CComPtr<IDebugClient5> m_client;
CComPtr<IDebugControl4> m_control;
};
/////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd
//#include "dbgext.h"
//#include "dbgeventcb.h"
//

View File

@ -1,4 +1,9 @@
#include "stdafx.h"
//#include "dbgexcept.h"
//
///////////////////////////////////////////////////////////////////////////////////

View File

@ -1,5 +1,45 @@
#pragma once
#include <exception>
#include <string>
namespace pykd {
/////////////////////////////////////////////////////////////////////////////////
class DbgException : public std::exception
{
public:
DbgException( const std::string &desc ) :
std::exception( desc.c_str() )
{}
const char* getDesc() const {
return what();
}
static
void
exceptionTranslate(const DbgException &e );
};
///////////////////////////////////////////////////////////////////////////////////
extern PyObject *baseExceptionType;
///////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd
///////////////////////////////////////////////////////////////////////////////////
//#include <exception>
//#include <string>
//

View File

@ -2,6 +2,12 @@
#include <dbgeng.h>
#include "module.h"
#include "diawrapper.h"
#include "dbgclient.h"
namespace python = boost::python;
////////////////////////////////////////////////////////////////////////////////
HRESULT
@ -44,11 +50,18 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args )
////////////////////////////////////////////////////////////////////////////////
HRESULT
CALLBACK
info( PDEBUG_CLIENT4 client, PCSTR args )
BOOST_PYTHON_MODULE( pykd )
{
return S_OK;
python::class_<pykd::DebugClient>("dbgClient", "Class representing a debugging session" )
.def( "loadDump", &pykd::DebugClient::loadDump, "Load crash dump" )
.def( "startProcess", &pykd::DebugClient::startProcess, "Start process for debugging" )
.def( "attachProcess", &pykd::DebugClient::attachProcess, "Attach debugger to a exsisting process" )
.def( "attachKernel", &pykd::DebugClient::attachKernel, "Attach debugger to a target's kernel" );
python::class_<pykd::Module>("module", "Class representing executable module", python::no_init )
.def( python::init<std::string>( "constructor" ) );
// python::class_<pykd::DiaWrapper>("dia", "class wrapper for MS DIA" );
}
////////////////////////////////////////////////////////////////////////////////
@ -61,6 +74,9 @@ info( PDEBUG_CLIENT4 client, PCSTR args )
//#include <wdbgexts.h>
//
//#include <string>

View File

@ -1,5 +1,22 @@
#pragma once
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
class Module {
public:
Module( const std::string &moduleName )
{}
};
///////////////////////////////////////////////////////////////////////////////////
};
//#include <string>
//#include <map>
//

View File

@ -1,7 +1,5 @@
EXPORTS
DebugExtensionInitialize
DebugExtensionUninitialize
info
py
pycmd

View File

@ -349,10 +349,22 @@
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\dbgclient.cpp"
>
</File>
<File
RelativePath=".\dbgexcept.cpp"
>
</File>
<File
RelativePath=".\dbgext.cpp"
>
</File>
<File
RelativePath=".\module.cpp"
>
</File>
<File
RelativePath=".\pykd.def"
>
@ -399,6 +411,22 @@
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\dbgclient.h"
>
</File>
<File
RelativePath=".\dbgexcept.h"
>
</File>
<File
RelativePath=".\diawrapper.h"
>
</File>
<File
RelativePath=".\module.h"
>
</File>
<File
RelativePath=".\resource.h"
>

View File

@ -30,20 +30,22 @@
#include <windows.h>
#include <atlbase.h>
//
//#ifndef __field_ecount_opt
//#define __field_ecount_opt(x)
//#endif // __field_ecount_opt
//
//
//#define BOOST_PYTHON_STATIC_LIB
//
//#pragma warning(push)
//// 'return' : conversion from 'Py_ssize_t' to 'unsigned int', possible loss of data
//#pragma warning(disable:4244)
//#include <boost/python.hpp>
//#include <boost/python/object.hpp>
//#pragma warning(pop)
#define BOOST_PYTHON_STATIC_LIB
#pragma warning(push)
// 'return' : conversion from 'Py_ssize_t' to 'unsigned int', possible loss of data
#pragma warning(disable:4244)
#include <boost/python.hpp>
#include <boost/python/object.hpp>
#include <boost/python/module.hpp>
#pragma warning(pop)
//
//#include <vector>
//

View File

@ -4,11 +4,12 @@
import unittest
import target
import pykd
class BaseTest( unittest.TestCase ):
def test1( self ):
self.assertNotEqual( target.module, None )
def testImport( self ):
self.assertNotEqual( None, pykd.module )
self.assertNotEqual( None, pykd.dbgClient )
# self.assertNotEqual( None, pykd.dia )

View File

@ -5,7 +5,6 @@
import sys
import os
import unittest
import fnmatch
# Dynamically append current pykd.pyd path to PYTHONPATH
sys.path.append(os.path.dirname(sys.argv[1]))
@ -15,11 +14,15 @@ import target
import basetest
import typeinfo
import regtest
import moduletest
print dir(pykd)
def getTestSuite( singleName = "" ):
if singleName == "":
return unittest.TestSuite(
[ unittest.TestLoader().loadTestsFromTestCase( basetest.BaseTest ),
unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ),
# unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
# unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest )
] )
@ -34,10 +37,12 @@ if __name__ == "__main__":
target.moduleName = os.path.splitext(os.path.basename(targetAppPath))[0]
print "\nTest module: %s" % targetAppPath
pykd.startProcess( targetAppPath )
pykd.go()
dbg = pykd.dbgClient()
dbg.startProcess( targetAppPath )
# pykd.go()
target.module = pykd.loadModule( target.moduleName )
# target.module = pykd.loadModule( target.moduleName )
suite = getTestSuite()

View File

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