diff --git a/pykd/dbgengine.h b/pykd/dbgengine.h index 4ae318c..4e68874 100644 --- a/pykd/dbgengine.h +++ b/pykd/dbgengine.h @@ -141,6 +141,7 @@ ULONG64 getCurrentProcess(); ULONG64 getImplicitThread(); void setCurrentProcess( ULONG64 processAddr ); void setImplicitThread( ULONG64 threadAddr ); +void getAllProcessThreads( std::vector &threadsArray ); // Symbol path std::string getSymbolPath(); diff --git a/pykd/pymod.cpp b/pykd/python/pymod.cpp similarity index 97% rename from pykd/pymod.cpp rename to pykd/python/pymod.cpp index f55a0c5..ecd7afc 100644 --- a/pykd/pymod.cpp +++ b/pykd/python/pymod.cpp @@ -21,13 +21,14 @@ #include "stkframe.h" #include "bpoint.h" #include "eventhandler.h" +#include "pysupport.h" #include "win/dbgio.h" #include "win/windbg.h" using namespace pykd; -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// static const std::string pykdVersion = PYKD_VERSION_BUILD_STR #ifdef _DEBUG @@ -281,6 +282,8 @@ BOOST_PYTHON_MODULE( pykd ) "Set current process by address" ); python::def( "setImplicitThread", &setImplicitThread, "Set implicit thread for current process" ); + python::def( "getProcessThreads", &pysupport::getProcessThreads, + "Get all process's threads ( user mode only )" ); // symbol path python::def( "getSymbolPath", &getSymbolPath, "Returns current symbol path"); diff --git a/pykd/python/pysupport.cpp b/pykd/python/pysupport.cpp new file mode 100644 index 0000000..e3b188c --- /dev/null +++ b/pykd/python/pysupport.cpp @@ -0,0 +1,30 @@ +#include "stdafx.h" +#include "pysupport.h" + +#include "dbgengine.h" +#include + +/////////////////////////////////////////////////////////////////////////////// + +namespace pykd { +namespace pysupport { + +/////////////////////////////////////////////////////////////////////////////// + +python::list getProcessThreads() +{ + std::vector threads; + getAllProcessThreads( threads ); + + python::list threadsLst; + + std::vector::iterator it; + for ( it = threads.begin(); it != threads.end(); ++it ) + threadsLst.append( *it ); + + return threadsLst; +} + +/////////////////////////////////////////////////////////////////////////////// + +} } //pykd::support namespace end \ No newline at end of file diff --git a/pykd/python/pysupport.h b/pykd/python/pysupport.h new file mode 100644 index 0000000..f9a2139 --- /dev/null +++ b/pykd/python/pysupport.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +/////////////////////////////////////////////////////////////////////////////// + +namespace pykd { +namespace pysupport { + +python::list getProcessThreads(); + +} } //pykd::support namespace end + +/////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/win/dbgeng.cpp b/pykd/win/dbgeng.cpp index 48c387c..ddaacc3 100644 --- a/pykd/win/dbgeng.cpp +++ b/pykd/win/dbgeng.cpp @@ -1365,6 +1365,61 @@ void setImplicitThread( ULONG64 threadAddr ) /////////////////////////////////////////////////////////////////////////////// +void getAllProcessThreads( std::vector &threadsArray ) +{ + PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); + + HRESULT hres; + ULONG debugClass, debugQualifier; + + hres = g_dbgEng->control->GetDebuggeeType( &debugClass, &debugQualifier ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::GetDebuggeeType failed" ); + + if ( debugClass != DEBUG_CLASS_USER_WINDOWS ) + throw DbgException( "getAllProcessThreads routine only for usermode" ); + + ULONG threadsNumber = 0; + + hres = g_dbgEng->system->GetNumberThreads( &threadsNumber ); + if ( FAILED(hres) ) + throw DbgException( "IDebugSystemObjects::GetNumberThreads failed" ); + + std::vector ids(threadsNumber); + + hres = g_dbgEng->system->GetThreadIdsByIndex( 0, threadsNumber, &ids[0], NULL ); + if ( FAILED(hres) ) + throw DbgException( "IDebugSystemObjects::GetThreadIdsByIndex failed" ); + + ULONG currentThreadId; + hres = g_dbgEng->system->GetCurrentThreadId( ¤tThreadId ); + if ( FAILED(hres) ) + throw DbgException( "IDebugSystemObjects::GetCurrentThreadId failed" ); + + threadsArray.resize( threadsNumber ); + for ( size_t i = 0; i < threadsNumber; ++i ) + { + hres = g_dbgEng->system->SetCurrentThreadId( ids[i] ); + if ( FAILED(hres) ) + { + g_dbgEng->system->SetCurrentThreadId( currentThreadId ); + throw DbgException( "IDebugSystemObjects::SetCurrentThreadId failed" ); + } + + hres = g_dbgEng->system->GetCurrentThreadTeb( &threadsArray[i] ); + if ( FAILED(hres) ) + { + g_dbgEng->system->SetCurrentThreadId( currentThreadId ); + throw DbgException( "IDebugSystemObjects::GetCurrentThreadTeb failed" ); + } + } + + g_dbgEng->system->SetCurrentThreadId( currentThreadId ); +} + +/////////////////////////////////////////////////////////////////////////////// + ULONG64 loadExtension(const std::wstring &extPath ) { PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); diff --git a/test/targetapp/targetapp.vcproj b/test/targetapp/targetapp.vcproj index 226ad86..da0801f 100644 --- a/test/targetapp/targetapp.vcproj +++ b/test/targetapp/targetapp.vcproj @@ -1,7 +1,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -359,6 +502,22 @@ UsePrecompiledHeader="1" /> + + + + + +