pykd/pykd/dbgclient.cpp
SND\EreTIk_cp b708cfefe4 [0.1.x]
+ get local variables dict {name: typedVar, ....}
 ~ DiaSymbol::findEx add default params
 ~ re-query pdb-file name for module
 + dataKind for typedVar

git-svn-id: https://pykd.svn.codeplex.com/svn@73103 9b283d60-5439-405e-af05-b73fd8c4d996
2017-11-08 17:27:51 +04:00

441 lines
12 KiB
C++

#include "stdafx.h"
#include <vector>
#include "dbgclient.h"
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
DebugClientPtr g_dbgClient( DebugClient::createDbgClient() );
///////////////////////////////////////////////////////////////////////////////////
DebugClient::DebugClient( IDebugClient4 *client )
: DbgObject( client )
, m_symSymbols( new SyntheticSymbols(*m_symbols, *this) )
, m_internalDbgEventHandler(client, m_symSymbols)
{
}
///////////////////////////////////////////////////////////////////////////////////
DebugClientPtr DebugClient::createDbgClient() {
HRESULT hres;
CComPtr<IDebugClient4> client = NULL;
hres = DebugCreate( __uuidof(IDebugClient4), (void **)&client );
if ( FAILED( hres ) )
throw DbgException("DebugCreate failed");
return createDbgClient( client );
}
///////////////////////////////////////////////////////////////////////////////////
DebugClientPtr DebugClient::createDbgClient( IDebugClient4 *client ) {
HRESULT hres;
CComPtr<IDebugClient> newClient = NULL;
hres = client->CreateClient( &newClient );
if ( FAILED( hres ) )
throw DbgException("DebugCreate failed");
CComQIPtr<IDebugClient4> client4= newClient;
return DebugClientPtr( new DebugClient(client4) );
}
///////////////////////////////////////////////////////////////////////////////////
DebugClientPtr DebugClient::setDbgClientCurrent( DebugClientPtr newDbgClient ) {
DebugClientPtr oldClient = g_dbgClient;
g_dbgClient = newDbgClient;
return oldClient;
}
///////////////////////////////////////////////////////////////////////////////////
python::tuple DebugClient::getDebuggeeType()
{
HRESULT hres;
ULONG debugClass, debugQualifier;
hres = m_control->GetDebuggeeType( &debugClass, &debugQualifier );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetDebuggeeType failed" );
return python::make_tuple( debugClass, debugQualifier );
}
python::tuple getDebuggeeType()
{
return g_dbgClient->getDebuggeeType();
}
///////////////////////////////////////////////////////////////////////////////////
ULONG DebugClient::getExecutionStatus()
{
ULONG currentStatus;
HRESULT hres;
hres = m_control->GetExecutionStatus( &currentStatus );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetExecutionStatus failed" );
return currentStatus;
}
ULONG getExecutionStatus()
{
return g_dbgClient->getExecutionStatus();
}
///////////////////////////////////////////////////////////////////////////////////
bool DebugClient::is64bitSystem()
{
HRESULT hres;
hres = m_control->IsPointer64Bit();
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::IsPointer64Bit failed" );
return hres == S_OK;
}
bool
is64bitSystem()
{
return g_dbgClient->is64bitSystem();
}
///////////////////////////////////////////////////////////////////////////////////
bool DebugClient::isDumpAnalyzing()
{
HRESULT hres;
ULONG debugClass, debugQualifier;
hres = m_control->GetDebuggeeType( &debugClass, &debugQualifier );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetDebuggeeType failed" );
return debugQualifier >= DEBUG_DUMP_SMALL;
}
bool isDumpAnalyzing()
{
return g_dbgClient->isDumpAnalyzing();
}
///////////////////////////////////////////////////////////////////////////////////
bool DebugClient::isKernelDebugging()
{
HRESULT hres;
ULONG debugClass, debugQualifier;
hres = m_control->GetDebuggeeType( &debugClass, &debugQualifier );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetDebuggeeType failed" );
return debugClass == DEBUG_CLASS_KERNEL;
}
bool isKernelDebugging()
{
return g_dbgClient->isKernelDebugging();
}
//////////////////////////////////////////////////////////////////////////////////
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 loadDump( const std::wstring &fileName ) {
g_dbgClient->loadDump( fileName );
}
///////////////////////////////////////////////////////////////////////////////////
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 startProcess( const std::wstring &processName ) {
g_dbgClient->startProcess( processName );
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::attachProcess( ULONG processId )
{
HRESULT hres;
hres = m_client->AttachProcess( 0, processId, 0 );
if ( FAILED( hres ) )
throw DbgException( "IDebugClient::AttachProcess failed" );
}
void attachProcess( ULONG processId ) {
g_dbgClient->attachProcess( processId );
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::detachProcess()
{
HRESULT hres;
hres = m_client->DetachCurrentProcess();
if ( FAILED( hres ) )
throw DbgException( "IDebugClient::DetachCurrentProcess failed" );
}
void detachProcess() {
g_dbgClient->detachProcess();
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::attachKernel( const std::wstring &param )
{
HRESULT hres;
hres = m_client5->AttachKernelWide( DEBUG_ATTACH_KERNEL_CONNECTION, param.c_str() );
if ( FAILED( hres ) )
throw DbgException( "IDebugClient5::AttachKernelWide failed" );
}
void attachKernel( const std::wstring &param ) {
g_dbgClient->attachKernel( param );
}
///////////////////////////////////////////////////////////////////////////////////
std::string DebugClient::findSymbol( ULONG64 offset )
{
HRESULT hres;
offset = addr64( offset );
char symbolName[0x100];
ULONG64 displace = 0;
hres = m_symbols->GetNameByOffset( offset, symbolName, sizeof(symbolName), NULL, &displace );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetNameByOffset failed" );
std::stringstream ss;
displace == 0 ? ss << symbolName : ss << symbolName << '+' << std::hex << displace;
return ss.str();
}
std::string findSymbol( ULONG64 offset )
{
return g_dbgClient->findSymbol( offset );
}
///////////////////////////////////////////////////////////////////////////////////
ULONG64 DebugClient::getOffset( const std::wstring symbolname )
{
HRESULT hres;
ULONG64 offset;
hres = m_symbols->GetOffsetByNameWide( symbolname.c_str(), &offset );
if ( FAILED( hres ) )
throw DbgException( "failed to find offset for symbol" );
return offset;
}
ULONG64 getOffset( const std::wstring symbolname )
{
return g_dbgClient->getOffset( symbolname );
}
///////////////////////////////////////////////////////////////////////////////////
std::string DebugClient::getPdbFile( ULONG64 moduleBase )
{
HRESULT hres;
IMAGEHLP_MODULEW64 imageHelpInfo = { 0 };
hres =
m_advanced->GetSymbolInformation(
DEBUG_SYMINFO_IMAGEHLP_MODULEW64,
moduleBase,
0,
&imageHelpInfo,
sizeof( imageHelpInfo ),
NULL,
NULL,
0,
NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" );
char fileName[ 256 ];
WideCharToMultiByte( CP_ACP, 0, imageHelpInfo.LoadedPdbName, 256, fileName, 256, NULL, NULL );
return std::string( fileName );
}
std::string getPdbFile( ULONG64 moduleBase )
{
return g_dbgClient->getPdbFile( moduleBase );
}
///////////////////////////////////////////////////////////////////////////////////
std::string DebugClient::dbgSymPath()
{
HRESULT hres;
std::string pathStr;
ULONG size;
m_symbols->GetSymbolPath( NULL, 0, &size );
std::vector<char> path(size);
hres = m_symbols->GetSymbolPath( &path[0], size, NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbols::GetSymbolPath failed" );
return std::string(&path[0],size);
}
std::string dbgSymPath()
{
return g_dbgClient->dbgSymPath();
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::setExecutionStatus( ULONG status )
{
HRESULT hres;
hres = m_control->SetExecutionStatus( status );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::SetExecutionStatus failed" );
}
void setExecutionStatus( ULONG status )
{
g_dbgClient->setExecutionStatus( status );
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::waitForEvent()
{
HRESULT hres;
do {
PyThread_StateRestore pyThreadRestore( m_pyThreadState );
hres = m_control->WaitForEvent( 0, INFINITE );
} while( false );
if ( FAILED( hres ) )
{
if (E_UNEXPECTED == hres)
throw WaitEventException();
throw DbgException( "IDebugControl::WaitForEvent failed" );
}
}
void waitForEvent()
{
g_dbgClient->waitForEvent();
}
///////////////////////////////////////////////////////////////////////////////////
ULONG DebugClient::ptrSize()
{
HRESULT hres;
hres = m_control->IsPointer64Bit();
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::IsPointer64Bit failed" );
return S_OK == hres ? 8 : 4;
}
///////////////////////////////////////////////////////////////////////////////////
ULONG ptrSize()
{
return g_dbgClient->ptrSize();
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::terminateProcess()
{
HRESULT hres;
hres = m_client->TerminateCurrentProcess();
if ( FAILED( hres ) )
throw DbgException( "IDebugClient::TerminateCurrentProcess failed" );
}
void terminateProcess()
{
g_dbgClient->terminateProcess();
}
///////////////////////////////////////////////////////////////////////////////////
}; // end of namespace pykd