diff --git a/pykd/dbgcmd.h b/pykd/dbgcmd.h index d262a0d..f81e2ec 100644 --- a/pykd/dbgcmd.h +++ b/pykd/dbgcmd.h @@ -2,9 +2,6 @@ #include -#include -#include - ///////////////////////////////////////////////////////////////////////////////// std::string diff --git a/pykd/dbgdump.cpp b/pykd/dbgdump.cpp index 0fddd84..a49e762 100644 --- a/pykd/dbgdump.cpp +++ b/pykd/dbgdump.cpp @@ -5,90 +5,54 @@ #include "dbgext.h" #include "dbgdump.h" #include "dbgexcept.h" +#include "dbgeventcb.h" #include "dbgsession.h" #include "dbgsystem.h" -#include "dbgcmd.h" ///////////////////////////////////////////////////////////////////////////////// -bool -dbgLoadDump( const std::wstring &fileName ) +std::string +dbgLoadDump( const std::string &fileName ) { HRESULT hres; try { - - if ( !dbgSessionStarted ) - dbgCreateSession(); - - hres = dbgExt->client4->OpenDumpFileWide( fileName.c_str(), NULL ); - + + std::vector fileNameW( fileName.size()+ 1 ); + + MultiByteToWideChar( + CP_ACP, + 0, + fileName.c_str(), + (ULONG)fileName.size() + 1, + &fileNameW[0], + (ULONG)fileName.size() + 1 ); + + hres = dbgExt->client4->OpenDumpFileWide( &fileNameW[0], NULL ); if ( FAILED( hres ) ) throw DbgException( "IDebugClient4::OpenDumpFileWide failed" ); hres = dbgExt->control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE); if ( FAILED( hres ) ) - throw DbgException( "IDebugControl::WaitForEvent failed" ); - - return true; + throw DbgException( "IDebugControl::WaitForEvent failed" ); + + setDbgSessionStarted(); + + return "loaded ok"; } catch( std::exception& ) { - + //g_Ext->Out( "pykd error: %s\n", e.what() ); } catch(...) { - dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); - } - - return false; -} - -///////////////////////////////////////////////////////////////////////////////// - -bool -startProcess( const std::wstring &processName ) -{ - HRESULT hres; - - try { - - if ( !dbgSessionStarted ) - dbgCreateSession(); - - ULONG opt; - hres = dbgExt->control->GetEngineOptions( &opt ); - if ( FAILED( hres ) ) - throw DbgException( "IDebugControl::GetEngineOptions failed" ); - - opt |= DEBUG_ENGOPT_INITIAL_BREAK; - hres = dbgExt->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 = dbgExt->client4->CreateProcessWide( 0, &cmdLine[0], DEBUG_PROCESS | DETACHED_PROCESS ); - if ( FAILED( hres ) ) - throw DbgException( "IDebugClient4::CreateProcessWide failed" ); - - hres = dbgExt->control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE); - if ( FAILED( hres ) ) - throw DbgException( "IDebugControl::WaitForEvent failed" ); - - return true; - } - catch( std::exception& e ) - { - dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() ); - } - catch(...) - { - dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); + //g_Ext->Out( "pykd unexpected error\n" ); } - return false; -} + std::string result = "failed to open dump "; + result += fileName; + + return result; +} ///////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/pykd/dbgdump.h b/pykd/dbgdump.h index 4cc6524..8c5f898 100644 --- a/pykd/dbgdump.h +++ b/pykd/dbgdump.h @@ -4,10 +4,7 @@ ///////////////////////////////////////////////////////////////////////////////// -bool -dbgLoadDump( const std::wstring &dumpName ); - -bool -startProcess( const std::wstring &processName ); +std::string +dbgLoadDump( const std::string &dumpName ); ///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgeventcb.cpp b/pykd/dbgeventcb.cpp new file mode 100644 index 0000000..6121cbe --- /dev/null +++ b/pykd/dbgeventcb.cpp @@ -0,0 +1,274 @@ + +#include "stdafx.h" + +#include "dbgext.h" +#include "dbgmem.h" +#include "dbgmodule.h" +#include "dbgexcept.h" +#include "dbgsynsym.h" +#include "dbgeventcb.h" + +///////////////////////////////////////////////////////////////////////////////// + +DbgEventCallbacks dbgEventCallbacks; + +///////////////////////////////////////////////////////////////////////////////// + +HRESULT DbgEventCallbacks::Register() +{ + HRESULT hres; + try + { + // monitor "global" WinDbg events + hres = DebugCreate( + __uuidof(IDebugSymbols), + reinterpret_cast(&m_dbgSymbols)); + if (FAILED(hres)) + throw hres; + + hres = DebugCreate( + __uuidof(IDebugSymbols3), + reinterpret_cast(&m_dbgSymbols3)); + if (FAILED(hres)) + throw hres; + + hres = DebugCreate( + __uuidof(IDebugClient), + reinterpret_cast(&m_dbgClient)); + if (FAILED(hres)) + throw hres; + + hres = m_dbgClient->GetEventCallbacks(&m_prevCallbacks); + if (FAILED(hres)) + throw hres; + + hres = m_dbgClient->SetEventCallbacks(this); + if (FAILED(hres)) + throw hres; + + hres = S_OK; + } + catch(HRESULT _hres) + { + hres = _hres; + } + catch(...) + { + hres = S_FALSE; + } + if (S_OK != hres) + Deregister(); + + return hres; +} + +///////////////////////////////////////////////////////////////////////////////// + +void DbgEventCallbacks::Deregister() +{ + if (m_dbgClient) + { + m_dbgClient->SetEventCallbacks(m_prevCallbacks); + + m_dbgClient->Release(); + m_dbgClient = NULL; + } + if (m_dbgSymbols) + { + m_dbgSymbols->Release(); + m_dbgSymbols = NULL; + } + if (m_dbgSymbols3) + { + m_dbgSymbols3->Release(); + m_dbgSymbols3 = NULL; + } +} + +///////////////////////////////////////////////////////////////////////////////// + +COM_DECLSPEC_NOTHROW HRESULT DbgEventCallbacks::GetInterestMask( + __out PULONG Mask +) +{ + *Mask = DEBUG_EVENT_CHANGE_SYMBOL_STATE; + return S_OK; +} +///////////////////////////////////////////////////////////////////////////////// + +COM_DECLSPEC_NOTHROW HRESULT DbgEventCallbacks::Breakpoint( + __in PDEBUG_BREAKPOINT /* Bp */ +) +{ + return DEBUG_STATUS_IGNORE_EVENT; +} + +///////////////////////////////////////////////////////////////////////////////// + +COM_DECLSPEC_NOTHROW HRESULT DbgEventCallbacks::Exception( + __in PEXCEPTION_RECORD64 /* Exception */, + __in ULONG /* FirstChance */ +) +{ + return DEBUG_STATUS_IGNORE_EVENT; +} + +///////////////////////////////////////////////////////////////////////////////// + +COM_DECLSPEC_NOTHROW HRESULT DbgEventCallbacks::CreateThread( + __in ULONG64 /* Handle */, + __in ULONG64 /* DataOffset */, + __in ULONG64 /* StartOffset */ +) +{ + return DEBUG_STATUS_IGNORE_EVENT; +} + +///////////////////////////////////////////////////////////////////////////////// + +COM_DECLSPEC_NOTHROW HRESULT DbgEventCallbacks::ExitThread( + __in ULONG /* ExitCode */ +) +{ + return DEBUG_STATUS_IGNORE_EVENT; +} + +///////////////////////////////////////////////////////////////////////////////// + +COM_DECLSPEC_NOTHROW HRESULT DbgEventCallbacks::CreateProcess( + __in ULONG64 /* ImageFileHandle */, + __in ULONG64 /* Handle */, + __in ULONG64 /* BaseOffset */, + __in ULONG /* ModuleSize */, + __in_opt PCSTR /* ModuleName */, + __in_opt PCSTR /* ImageName */, + __in ULONG /* CheckSum */, + __in ULONG /* TimeDateStamp */, + __in ULONG64 /* InitialThreadHandle */, + __in ULONG64 /* ThreadDataOffset */, + __in ULONG64 /* StartOffset */ +) +{ + return DEBUG_STATUS_IGNORE_EVENT; +} + +///////////////////////////////////////////////////////////////////////////////// + +COM_DECLSPEC_NOTHROW HRESULT DbgEventCallbacks::ExitProcess( + __in ULONG /* ExitCode */ +) +{ + return DEBUG_STATUS_IGNORE_EVENT; +} + +///////////////////////////////////////////////////////////////////////////////// + +COM_DECLSPEC_NOTHROW HRESULT DbgEventCallbacks::LoadModule( + __in ULONG64 /* ImageFileHandle */, + __in ULONG64 /* BaseOffset */, + __in ULONG /* ModuleSize */, + __in_opt PCSTR /* ModuleName */, + __in_opt PCSTR /* ImageName */, + __in ULONG /* CheckSum */, + __in ULONG /* TimeDateStamp*/ +) +{ + return DEBUG_STATUS_IGNORE_EVENT; +} + +///////////////////////////////////////////////////////////////////////////////// + +COM_DECLSPEC_NOTHROW HRESULT DbgEventCallbacks::UnloadModule( + __in_opt PCSTR /* ImageBaseName */, + __in ULONG64 /* BaseOffset */ +) +{ + return DEBUG_STATUS_IGNORE_EVENT; +} + +///////////////////////////////////////////////////////////////////////////////// + +COM_DECLSPEC_NOTHROW HRESULT DbgEventCallbacks::SystemError( + __in ULONG /* Error */, + __in ULONG /* Level */ +) +{ + return DEBUG_STATUS_IGNORE_EVENT; +} + +///////////////////////////////////////////////////////////////////////////////// + +COM_DECLSPEC_NOTHROW HRESULT DbgEventCallbacks::SessionStatus( + __in ULONG /* Status */ +) +{ + return DEBUG_STATUS_IGNORE_EVENT; +} + +///////////////////////////////////////////////////////////////////////////////// + +COM_DECLSPEC_NOTHROW HRESULT DbgEventCallbacks::ChangeDebuggeeState( + __in ULONG /* Flags */, + __in ULONG64 /* Argument */ +) +{ + return DEBUG_STATUS_IGNORE_EVENT; +} + +///////////////////////////////////////////////////////////////////////////////// + +COM_DECLSPEC_NOTHROW HRESULT DbgEventCallbacks::ChangeEngineState( + __in ULONG /* Flags */, + __in ULONG64 /* Argument */ +) +{ + return DEBUG_STATUS_IGNORE_EVENT; +} + +///////////////////////////////////////////////////////////////////////////////// + +COM_DECLSPEC_NOTHROW HRESULT DbgEventCallbacks::ChangeSymbolState( + __in ULONG Flags, + __in ULONG64 Argument +) +{ + if ((DEBUG_CSS_LOADS & Flags)) + { + if (Argument) + return doSymbolsLoaded(Argument); + + // f.e. is case ".reload /f image.exe", if for image.exe no symbols + restoreSyntheticSymbolForAllModules(m_dbgSymbols, m_dbgSymbols3); + return S_OK; + } + + return DEBUG_STATUS_IGNORE_EVENT; +} + +///////////////////////////////////////////////////////////////////////////////// + +HRESULT DbgEventCallbacks::doSymbolsLoaded( + ULONG64 moduleBase +) +{ + try + { + DEBUG_MODULE_PARAMETERS dbgModuleParameters; + HRESULT hres = m_dbgSymbols->GetModuleParameters( + 1, + &moduleBase, + 0, + &dbgModuleParameters); + if (SUCCEEDED(hres)) + { + ModuleInfo moduleInfo(dbgModuleParameters); + restoreSyntheticSymbolForModule(moduleInfo, m_dbgSymbols3); + } + } + catch (...) + { + } + return S_OK; +} + +///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgeventcb.h b/pykd/dbgeventcb.h new file mode 100644 index 0000000..f3d2970 --- /dev/null +++ b/pykd/dbgeventcb.h @@ -0,0 +1,145 @@ + +#pragma once + +// monitoring and processing debug events +class DbgEventCallbacks : public IDebugEventCallbacks +{ +public: + + DbgEventCallbacks() + : m_dbgClient(NULL) + , m_prevCallbacks(NULL) + , m_dbgSymbols(NULL) + , m_dbgSymbols3(NULL) + { + } + ~DbgEventCallbacks() + { + Deregister(); + } + + // [de]register debug event handler + HRESULT Register(); + void Deregister(); + +private: + + ///////////////////////////////////////////////////////////////////////////////// + // IUnknown interface implementation + + STDMETHOD(QueryInterface)(__in REFIID InterfaceId, __out PVOID *Interface) + { + if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) || + IsEqualIID(InterfaceId, __uuidof(IDebugEventCallbacks))) + { + *Interface = this; + return S_OK; + } + return E_NOINTERFACE; + } + STDMETHOD_(ULONG, AddRef)() { return 2; } + STDMETHOD_(ULONG, Release)() { return 1; } + + ///////////////////////////////////////////////////////////////////////////////// + // IDebugEventCallbacks interface implementation + + STDMETHOD(GetInterestMask)( + __out PULONG Mask + ); + + STDMETHOD(Breakpoint)( + __in PDEBUG_BREAKPOINT Bp + ); + + STDMETHOD(Exception)( + __in PEXCEPTION_RECORD64 Exception, + __in ULONG FirstChance + ); + + STDMETHOD(CreateThread)( + __in ULONG64 Handle, + __in ULONG64 DataOffset, + __in ULONG64 StartOffset + ); + + STDMETHOD(ExitThread)( + __in ULONG ExitCode + ); + + STDMETHOD(CreateProcess)( + __in ULONG64 ImageFileHandle, + __in ULONG64 Handle, + __in ULONG64 BaseOffset, + __in ULONG ModuleSize, + __in_opt PCSTR ModuleName, + __in_opt PCSTR ImageName, + __in ULONG CheckSum, + __in ULONG TimeDateStamp, + __in ULONG64 InitialThreadHandle, + __in ULONG64 ThreadDataOffset, + __in ULONG64 StartOffset + ); + + STDMETHOD(ExitProcess)( + __in ULONG ExitCode + ); + + STDMETHOD(LoadModule)( + __in ULONG64 ImageFileHandle, + __in ULONG64 BaseOffset, + __in ULONG ModuleSize, + __in_opt PCSTR ModuleName, + __in_opt PCSTR ImageName, + __in ULONG CheckSum, + __in ULONG TimeDateStamp + ); + + STDMETHOD(UnloadModule)( + __in_opt PCSTR ImageBaseName, + __in ULONG64 BaseOffset + ); + + STDMETHOD(SystemError)( + __in ULONG Error, + __in ULONG Level + ); + + STDMETHOD(SessionStatus)( + __in ULONG Status + ); + + STDMETHOD(ChangeDebuggeeState)( + __in ULONG Flags, + __in ULONG64 Argument + ); + + STDMETHOD(ChangeEngineState)( + __in ULONG Flags, + __in ULONG64 Argument + ); + + STDMETHOD(ChangeSymbolState)( + __in ULONG Flags, + __in ULONG64 Argument + ); + + ///////////////////////////////////////////////////////////////////////////////// + + HRESULT doSymbolsLoaded( + ULONG64 moduleBase + ); + + ///////////////////////////////////////////////////////////////////////////////// + + IDebugClient *m_dbgClient; + IDebugEventCallbacks *m_prevCallbacks; + IDebugSymbols *m_dbgSymbols; + IDebugSymbols3 *m_dbgSymbols3; +}; + +///////////////////////////////////////////////////////////////////////////////// +// global singleton + +extern DbgEventCallbacks dbgEventCallbacks; + +///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 23aad65..ac0fc15 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -5,8 +5,6 @@ #include #include -#include -#include #include #include #include @@ -15,7 +13,7 @@ #include "dbgext.h" #include "dbgprint.h" #include "dbgreg.h" -#include "dbgtype.h" +#include "dbgtype.h" #include "dbgmodule.h" #include "dbgsym.h" #include "dbgmem.h" @@ -23,11 +21,13 @@ #include "dbgcmd.h" #include "dbgdump.h" #include "dbgexcept.h" +#include "dbgeventcb.h" #include "dbgsession.h" #include "dbgcallback.h" #include "dbgpath.h" #include "dbginput.h" #include "dbgprocess.h" +#include "dbgsynsym.h" ///////////////////////////////////////////////////////////////////////////////// @@ -54,7 +54,7 @@ public: sys.attr("stdout") = boost::python::object( dout ); dbgIn din; - sys.attr("stdin") = boost::python::object( din ); + sys.attr("stdin") = boost::python::object( din ); } boost::python::object @@ -91,13 +91,12 @@ BOOST_PYTHON_MODULE( pykd ) boost::python::def( "trace", &setExecutionStatus ); boost::python::def( "step", &setExecutionStatus ); boost::python::def( "expr", &evaluate ); - boost::python::def( "createSession", &dbgCreateSession ); // depricated + boost::python::def( "createSession", &dbgCreateSession ); boost::python::def( "isSessionStart", &dbgIsSessionStart ); boost::python::def( "symbolsPath", &dbgSymPath ); boost::python::def( "dprint", &DbgPrint::dprint, dprint( boost::python::args( "str", "dml" ), "" ) ); boost::python::def( "dprintln", &DbgPrint::dprintln, dprintln( boost::python::args( "str", "dml" ), "" ) ); boost::python::def( "loadDump", &dbgLoadDump ); - boost::python::def( "startProcess", &startProcess ); boost::python::def( "dbgCommand", &dbgCommand ); boost::python::def( "isValid", &isOffsetValid ); boost::python::def( "is64bitSystem", &is64bitSystem ); @@ -153,6 +152,9 @@ BOOST_PYTHON_MODULE( pykd ) boost::python::def( "getProcessorMode", &getProcessorMode ); boost::python::def( "setProcessorMode", &setProcessorMode ); boost::python::def( "addSynSymbol", &addSyntheticSymbol ); + boost::python::def( "delAllSynSymbols", &delAllSyntheticSymbols); + boost::python::def( "delSynSymbol", &delSyntheticSymbol ); + boost::python::def( "delSynSymbolsMask", &delSyntheticSymbolsMask); boost::python::class_ >( "typeClass" ) .def("sizeof", &typeClass::size ) .def("offset", &typeClass::getOffset ) @@ -167,6 +169,9 @@ BOOST_PYTHON_MODULE( pykd ) .def("image", &dbgModuleClass::getImageSymbolName ) .def("pdb", &dbgModuleClass::getPdbName ) .def("addSynSymbol", &dbgModuleClass::addSyntheticSymbol ) + .def("delAllSynSymbols", &dbgModuleClass::delAllSyntheticSymbols ) + .def("delSynSymbol", &dbgModuleClass::delSyntheticSymbol ) + .def("delSynSymbolsMask", &dbgModuleClass::delSyntheticSymbolsMask ) .def("__getattr__", &dbgModuleClass::getOffset ) .def("__str__", &dbgModuleClass::print ); boost::python::class_( @@ -206,15 +211,15 @@ DebugExtensionInitialize( { *Version = DEBUG_EXTENSION_VERSION( 1, 0 ); *Flags = 0; - + PyImport_AppendInittab("pykd", initpykd ); - + Py_Initialize(); - + windbgGlobalSession = new WindbgGlobalSession(); - - dbgSessionStarted = true; - + + setDbgSessionStarted(); + return S_OK; } @@ -254,7 +259,7 @@ SetupDebugEngine( IDebugClient4 *client, DbgExt *dbgExt ) client->QueryInterface( __uuidof(IDebugSystemObjects), (void**)&dbgExt->system ); client->QueryInterface( __uuidof(IDebugSystemObjects2), (void**)&dbgExt->system2 ); } - + ///////////////////////////////////////////////////////////////////////////////// HRESULT @@ -268,12 +273,11 @@ py( PDEBUG_CLIENT4 client, PCSTR args) try { DbgExt ext = { 0 }; - - SetupDebugEngine( client, &ext ); - dbgExt = &ext; - + SetupDebugEngine( client, &ext ); + dbgExt = &ext; + boost::python::import( "pykd" ); - + boost::python::object main = boost::python::import("__main__"); boost::python::object global(main.attr("__dict__")); @@ -383,17 +387,19 @@ CALLBACK pycmd( PDEBUG_CLIENT4 client, PCSTR args ) { try { - + + DbgExt ext = { 0 }; - - SetupDebugEngine( client, &ext ); - dbgExt = &ext; - + + SetupDebugEngine( client, &ext ); + dbgExt = &ext; + if ( !std::string( args ).empty() ) { - try { + try + { boost::python::exec( args, windbgGlobalSession->global(), windbgGlobalSession->global() ); - } + } catch( boost::python::error_already_set const & ) { // ошибка в скрипте @@ -420,7 +426,7 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args ) char str[100]; ULONG inputSize; bool stopInput = false; - + do { std::string output; @@ -485,13 +491,13 @@ CALLBACK pythonpath( PDEBUG_CLIENT4 client, PCSTR args ) { DbgExt ext = { 0 }; - + SetupDebugEngine( client, &ext ); - dbgExt = &ext; + dbgExt = &ext; //DbgPrint::dprintln( dbgPythonPath.getStr() ); - - return S_OK; + + return S_OK; } ///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgext.h b/pykd/dbgext.h index 1fd6a8e..7553491 100644 --- a/pykd/dbgext.h +++ b/pykd/dbgext.h @@ -29,5 +29,5 @@ struct DbgExt { extern DbgExt *dbgExt; void -SetupDebugEngine( IDebugClient4 *client, DbgExt *dbgExt ); +SetupDebugEngine( IDebugClient4 *client, DbgExt *dbgExt ); diff --git a/pykd/dbginput.h b/pykd/dbginput.h index a1a67f7..0612685 100644 --- a/pykd/dbginput.h +++ b/pykd/dbginput.h @@ -1,8 +1,6 @@ #pragma once #include "dbgprint.h" -#include -#include ///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgmem.h b/pykd/dbgmem.h index a9b57ba..6d1e40b 100644 --- a/pykd/dbgmem.h +++ b/pykd/dbgmem.h @@ -1,7 +1,5 @@ #pragma once -#include -#include #include ///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgmodule.cpp b/pykd/dbgmodule.cpp index 22cbe48..e5f4546 100644 --- a/pykd/dbgmodule.cpp +++ b/pykd/dbgmodule.cpp @@ -4,11 +4,12 @@ #include #include "dbgext.h" +#include "dbgmem.h" #include "dbgmodule.h" #include "dbgexcept.h" -#include "dbgmem.h" #include "dbgsym.h" #include "dbgcallback.h" +#include "dbgsynsym.h" ///////////////////////////////////////////////////////////////////////////////// @@ -111,7 +112,7 @@ dbgModuleClass::dbgModuleClass( const std::string &name, ULONG64 base, ULONG siz m_end( base + size ) { reloadSymbols(); - + std::string pattern = name + "!*"; ULONG64 enumHandle = 0; @@ -131,17 +132,17 @@ dbgModuleClass::dbgModuleClass( const std::string &name, ULONG64 base, ULONG siz &offset ); if ( FAILED( hres ) ) - break; - + break; + std::string symbolName( nameBuf ); - + symbolName.erase( 0, name.size() + 1 ); - + m_offsets.insert( std::make_pair( symbolName, offset ) ); } - + if ( enumHandle ) - dbgExt->symbols->EndSymbolMatch( enumHandle ); + dbgExt->symbols->EndSymbolMatch( enumHandle ); memset( &m_debugInfo, 0, sizeof( m_debugInfo ) ); @@ -155,10 +156,10 @@ dbgModuleClass::dbgModuleClass( const std::string &name, ULONG64 base, ULONG siz NULL, 0, NULL ); - + if ( SUCCEEDED( hres ) ) getImagePath(); -} +} ///////////////////////////////////////////////////////////////////////////////// @@ -226,19 +227,45 @@ dbgModuleClass::getOffset( const std::string &symName ) { return offset->second; } - - return 0; + ModuleInfo moduleInfo(m_debugInfo); + return ::getSyntheticSymbol(moduleInfo, symName); } ///////////////////////////////////////////////////////////////////////////////// -void dbgModuleClass::addSyntheticSymbol( +bool dbgModuleClass::addSyntheticSymbol( ULONG64 offset, ULONG size, const std::string &symName ) { - ::addSyntheticSymbol(m_base + offset, size, symName); + ModuleInfo moduleInfo(m_debugInfo); + return ::addSyntheticSymbolForModule(offset, size, symName, moduleInfo); +} + +///////////////////////////////////////////////////////////////////////////////// + +void dbgModuleClass::delAllSyntheticSymbols() +{ + ModuleInfo moduleInfo(m_debugInfo); + ::delAllSyntheticSymbolsForModule(moduleInfo); +} + +///////////////////////////////////////////////////////////////////////////////// + +ULONG dbgModuleClass::delSyntheticSymbol( + ULONG64 offset +) +{ + ModuleInfo moduleInfo(m_debugInfo); + return ::delSyntheticSymbolForModule(offset, moduleInfo); +} + +///////////////////////////////////////////////////////////////////////////////// + +ULONG dbgModuleClass::delSyntheticSymbolsMask( const std::string &symName ) +{ + return ::delSyntheticSymbolsMask(m_name, symName); } ///////////////////////////////////////////////////////////////////////////////// @@ -325,7 +352,15 @@ dbgModuleClass::print() const "%1$016x %2$016x %3$20s %4$20s" : "%1$08x %2$08x %3$20s %4$20s"); boost::format fmt(format_string); std::vector v(MAX_PATH); - ::WideCharToMultiByte( CP_ACP, 0, m_imageFullName.c_str(), -1, &v[0], v.size(), 0, 0); + ::WideCharToMultiByte( + CP_ACP, + 0, + m_imageFullName.c_str(), + -1, + &v[0], + (ULONG)v.size(), + 0, + 0); std::string fullname(&v[0]); fmt % m_base % (m_end - m_base) % m_name % fullname; return fmt.str(); @@ -341,31 +376,4 @@ dbgModuleClass::print() const return ""; } -///////////////////////////////////////////////////////////////////////////////// - -void -addSyntheticSymbol( ULONG64 addr, ULONG size, const std::string &symName ) -{ - try - { - HRESULT hres = - dbgExt->symbols3->AddSyntheticSymbol( - addr, - size, - symName.c_str(), - DEBUG_ADDSYNTHSYM_DEFAULT, - NULL); - if ( FAILED( hres ) ) - throw DbgException( "IDebugSymbol3::AddSyntheticSymbol failed" ); - } - catch( std::exception &e ) - { - dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() ); - } - catch(...) - { - dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); - } -} - ///////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/pykd/dbgmodule.h b/pykd/dbgmodule.h index 80bfc32..3eb0d82 100644 --- a/pykd/dbgmodule.h +++ b/pykd/dbgmodule.h @@ -3,8 +3,55 @@ #include #include -#include -#include +///////////////////////////////////////////////////////////////////////////////// + +// global unique module data +// WARNING: add only numeric field or change operator < +struct ModuleInfo +{ + ULONG64 m_base; + ULONG m_timeDataStamp; + ULONG m_checkSumm; + + ModuleInfo() + : m_base(0) + , m_timeDataStamp(0) + , m_checkSumm(0) + { + } + ModuleInfo( + const ModuleInfo &rhs + ) : m_base(rhs.m_base) + , m_timeDataStamp(rhs.m_timeDataStamp) + , m_checkSumm(rhs.m_checkSumm) + { + } + ModuleInfo( + const IMAGEHLP_MODULEW64 &dbgImageHelperInfo + ) : m_base(addr64(dbgImageHelperInfo.BaseOfImage)) + , m_timeDataStamp(dbgImageHelperInfo.TimeDateStamp) + , m_checkSumm(dbgImageHelperInfo.CheckSum) + { + } + ModuleInfo( + const DEBUG_MODULE_PARAMETERS &dbgModuleParameters + ) : m_base(addr64(dbgModuleParameters.Base)) + , m_timeDataStamp(dbgModuleParameters.TimeDateStamp) + , m_checkSumm(dbgModuleParameters.Checksum) + { + } + + bool operator ==(const ModuleInfo &rhs) const + { + return m_base == rhs.m_base + && m_timeDataStamp == rhs.m_timeDataStamp + && m_checkSumm == rhs.m_checkSumm; + } + bool operator < (const ModuleInfo &rhs) const + { + return memcmp(this, &rhs, sizeof(ModuleInfo)) < 0; + } +}; ///////////////////////////////////////////////////////////////////////////////// @@ -53,33 +100,41 @@ public: return m_imageFullName; } - std::wstring + std::wstring getPdbName() const { return std::wstring( m_debugInfo.LoadedPdbName ); } - void + bool addSyntheticSymbol( ULONG64 offset, ULONG size, const std::string &symName ); - + void + delAllSyntheticSymbols(); + + ULONG + delSyntheticSymbol( ULONG64 offset ); + + ULONG + delSyntheticSymbolsMask( const std::string &symName ); + std::string print() const; - + private: ULONG64 m_base; - + ULONG64 m_end; - + std::string m_name; - + std::wstring m_imageFullName; IMAGEHLP_MODULEW64 m_debugInfo; - + typedef std::map OffsetMap; OffsetMap m_offsets; - + void getImagePath(); }; @@ -93,7 +148,4 @@ loadModule( const std::string &moduleName ); boost::python::object findModule( ULONG64 addr ); -void -addSyntheticSymbol( ULONG64 addr, ULONG size, const std::string &symName ); - ///////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/pykd/dbgpath.cpp b/pykd/dbgpath.cpp index dc9a18e..e2ea4d2 100644 --- a/pykd/dbgpath.cpp +++ b/pykd/dbgpath.cpp @@ -5,7 +5,6 @@ #include "dbgpath.h" #include -#include /////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgprint.h b/pykd/dbgprint.h index 0f133c7..3f380a4 100644 --- a/pykd/dbgprint.h +++ b/pykd/dbgprint.h @@ -3,8 +3,6 @@ #pragma once #include -#include -#include class DbgPrint { diff --git a/pykd/dbgprocess.h b/pykd/dbgprocess.h index 9e8805a..a1c2566 100644 --- a/pykd/dbgprocess.h +++ b/pykd/dbgprocess.h @@ -1,7 +1,5 @@ #pragma once -#include -#include #include ///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgreg.h b/pykd/dbgreg.h index b43ef27..3f24cda 100644 --- a/pykd/dbgreg.h +++ b/pykd/dbgreg.h @@ -2,9 +2,6 @@ #include -#include -#include - ///////////////////////////////////////////////////////////////////////////////// boost::python::object diff --git a/pykd/dbgsession.cpp b/pykd/dbgsession.cpp index 0107325..93fab2c 100644 --- a/pykd/dbgsession.cpp +++ b/pykd/dbgsession.cpp @@ -1,7 +1,8 @@ #include "stdafx.h" -#include "dbgsession.h" #include "dbgext.h" +#include "dbgeventcb.h" +#include "dbgsession.h" DbgExt dbgGlobalSession = { 0 }; @@ -11,12 +12,12 @@ void dbgCreateSession() { IDebugClient4 *client = NULL; - DebugCreate( __uuidof(IDebugClient4), (void **)&client ); - + DebugCreate( __uuidof(IDebugClient4), (void **)&client ); + SetupDebugEngine( client, &dbgGlobalSession ); dbgExt = &dbgGlobalSession; - - dbgSessionStarted = true; + + setDbgSessionStarted(); } bool diff --git a/pykd/dbgsession.h b/pykd/dbgsession.h index ca41e49..8fb2d7f 100644 --- a/pykd/dbgsession.h +++ b/pykd/dbgsession.h @@ -6,6 +6,13 @@ dbgCreateSession(); extern bool dbgSessionStarted; +inline void setDbgSessionStarted() +{ + dbgEventCallbacks.Register(); + + dbgSessionStarted = true; +} + bool dbgIsSessionStart(); diff --git a/pykd/dbgsym.h b/pykd/dbgsym.h index 864d441..8fd6b41 100644 --- a/pykd/dbgsym.h +++ b/pykd/dbgsym.h @@ -2,9 +2,6 @@ #include -#include -#include - ///////////////////////////////////////////////////////////////////////////////// boost::python::object diff --git a/pykd/dbgsynsym.cpp b/pykd/dbgsynsym.cpp new file mode 100644 index 0000000..2f4b1ab --- /dev/null +++ b/pykd/dbgsynsym.cpp @@ -0,0 +1,677 @@ +#include "stdafx.h" + +#include +#include +#include +#include + +#include "dbgext.h" +#include "dbgmem.h" +#include "dbgmodule.h" +#include "dbgexcept.h" +#include "dbgsynsym.h" + +///////////////////////////////////////////////////////////////////////////////// + +struct SyntheticSymbol +{ + std::string m_name; + ULONG m_size; + + SyntheticSymbol() + : m_size(0) + { + } + SyntheticSymbol( + const std::string &name + ) : m_name(name) + , m_size(0) + { + } + SyntheticSymbol( + const SyntheticSymbol &rhs + ) : m_name(rhs.m_name) + , m_size(rhs.m_size) + { + } + + bool operator ==(const SyntheticSymbol &rhs) const + { + return m_name == rhs.m_name; + } +}; + +///////////////////////////////////////////////////////////////////////////////// + +// map of one module synthetic symbols +typedef std::map SynSymbolsForModule; + +// global synthetic symbols map by modules +typedef std::map SynSymbolsMap; + +// synchro-object for global synthetic symbols map +typedef boost::interprocess::interprocess_recursive_mutex SynSymbolsMapLockType; + +// scoped lock synchro-object for global synthetic symbols map +typedef boost::interprocess::scoped_lock SynSymbolsMapScopedLock; + +static struct _GlobalSyntheticSymbolMap : public SynSymbolsMap +{ + _GlobalSyntheticSymbolMap() : m_nRestoreAllModulesThread(0) {} + + SynSymbolsMapLockType m_Lock; + + // (**1) + // + // restoration of synthetic symbols for all modules can generate events of + // the synthetic symbols restoration for a specific module. + // perhaps this can give rise to event update to all modules (recursive) + // it is necessary to skip such a challenge + // + ULONG m_nRestoreAllModulesThread; +}g_SyntheticSymbolMap; + +#define _SynSymbolsMapScopedLock() \ + SynSymbolsMapScopedLock _lock(g_SyntheticSymbolMap.m_Lock) + +// (**1) for scope +struct ScopedAllModulesThread +{ + ScopedAllModulesThread( + ULONG &threadId = g_SyntheticSymbolMap.m_nRestoreAllModulesThread + ) : m_threadId(threadId) + { + m_threadId = GetCurrentThreadId(); + } + ~ScopedAllModulesThread() { m_threadId = 0; } + ULONG &m_threadId; +}; + +///////////////////////////////////////////////////////////////////////////////// + +bool addSyntheticSymbol( + ULONG64 addr, + ULONG size, + const std::string &symName +) +{ + try + { + + DEBUG_MODULE_AND_ID dbgModuleAndId = { 0 }; + addr = addr64(addr); + HRESULT hres = + dbgExt->symbols3->AddSyntheticSymbol( + addr, + size, + symName.c_str(), + DEBUG_ADDSYNTHSYM_DEFAULT, + &dbgModuleAndId); + if ( FAILED( hres ) ) + throw DbgException( "call IDebugSymbol3::AddSyntheticSymbol(...) failed" ); + + DEBUG_MODULE_PARAMETERS dbgModuleParameters; + hres = dbgExt->symbols->GetModuleParameters( + 1, + &dbgModuleAndId.ModuleBase, + 0, + &dbgModuleParameters); + if ( FAILED( hres ) ) + { + dbgExt->symbols3->RemoveSyntheticSymbol(&dbgModuleAndId); + throw DbgException( "call IDebugSymbol3::GetModuleParameters(...) failed" ); + } + + _SynSymbolsMapScopedLock(); + + ModuleInfo moduleInfo(dbgModuleParameters); + SynSymbolsForModule &mapSynSymbolsForModule = + g_SyntheticSymbolMap[moduleInfo]; + + ULONG64 addrSymbolOffset = addr - moduleInfo.m_base; + SyntheticSymbol &synSymbol = mapSynSymbolsForModule[addrSymbolOffset]; + + synSymbol.m_name = symName; + synSymbol.m_size = size; + + return true; + } + catch( std::exception &e ) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() ); + } + catch(...) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); + } + return false; +} + +///////////////////////////////////////////////////////////////////////////////// + +bool addSyntheticSymbolForModule( + ULONG64 offset, + ULONG size, + const std::string &symName, + const ModuleInfo &moduleInfo +) +{ + try + { + DEBUG_MODULE_AND_ID dbgModuleAndId = { 0 }; + offset = addr64(offset); + HRESULT hres = + dbgExt->symbols3->AddSyntheticSymbol( + offset + moduleInfo.m_base, + size, + symName.c_str(), + DEBUG_ADDSYNTHSYM_DEFAULT, + &dbgModuleAndId); + if ( FAILED( hres ) ) + throw DbgException( "call IDebugSymbol3::AddSyntheticSymbol(...) failed" ); + + { + DEBUG_MODULE_PARAMETERS dbgModuleParameters; + hres = dbgExt->symbols->GetModuleParameters( + 1, + &dbgModuleAndId.ModuleBase, + 0, + &dbgModuleParameters); + if ( FAILED( hres ) ) + { + dbgExt->symbols3->RemoveSyntheticSymbol(&dbgModuleAndId); + throw DbgException( "call IDebugSymbol3::GetModuleParameters(...) failed" ); + } + ModuleInfo gettedModuleInfo(dbgModuleParameters); + if (!(gettedModuleInfo == moduleInfo)) + { + // module mismatch + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd!" __FUNCTION__ " mismatch modules\n" ); + dbgExt->symbols3->RemoveSyntheticSymbol(&dbgModuleAndId); + return false; + } + } + + _SynSymbolsMapScopedLock(); + + SynSymbolsForModule &mapSynSymbolsForModule = + g_SyntheticSymbolMap[moduleInfo]; + + SyntheticSymbol &synSymbol = mapSynSymbolsForModule[offset]; + + synSymbol.m_name = symName; + synSymbol.m_size = size; + + return true; + } + catch( std::exception &e ) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() ); + } + catch(...) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); + } + return false; +} + +///////////////////////////////////////////////////////////////////////////////// + +struct SynSymbolNameCmp +{ + SynSymbolNameCmp(const std::string &symName ) : m_symName(symName) { } + bool operator() (const std::pair &rhs) const + { + return m_symName == rhs.second.m_name; + } + const std::string &m_symName; +}; + +///////////////////////////////////////////////////////////////////////////////// + +ULONG64 getSyntheticSymbol( + const ModuleInfo &moduleInfo, + const std::string &symName +) +{ + ULONG64 nAddress = 0; + + try + { + _SynSymbolsMapScopedLock(); + + // try find module + SynSymbolsMap::const_iterator itSynSymbols = + g_SyntheticSymbolMap.find( moduleInfo ); + if (itSynSymbols != g_SyntheticSymbolMap.end()) + { + // try find symbol by name + const SynSymbolsForModule &mapSynSymbolsForModule = itSynSymbols->second; + SynSymbolNameCmp nameCmp(symName); + + // FIXME: get first matched by name + SynSymbolsForModule::const_iterator itSynSymbol = + find_if( + mapSynSymbolsForModule.begin(), + mapSynSymbolsForModule.end(), + nameCmp); + if (itSynSymbol != mapSynSymbolsForModule.end()) + nAddress = moduleInfo.m_base + itSynSymbol->first; + } + } + catch( std::exception &e ) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() ); + } + catch(...) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); + } + + return nAddress; +} + +///////////////////////////////////////////////////////////////////////////////// + +// remove synthetic symbols by array of DEBUG_MODULE_AND_ID +inline ULONG RemoveSyntheticSymbols( + const std::vector &arrSymbols +) +{ + ULONG nResult = 0; + for (ULONG i = 0; i < arrSymbols.size(); ++i) + { + HRESULT hres = + dbgExt->symbols3->RemoveSyntheticSymbol( + const_cast(&arrSymbols[i])); + if (FAILED(hres)) + continue; + ++nResult; + } + return nResult; +} + +///////////////////////////////////////////////////////////////////////////////// + +static ULONG RemoveSynSymbolsByAddress(ULONG64 addr) +{ + ULONG nEntries = 0; + dbgExt->symbols3->GetSymbolEntriesByOffset( + addr, + 0, + NULL, + NULL, + 0, + &nEntries); + if (nEntries) + { + std::vector arrSymbols(nEntries); + HRESULT hres = dbgExt->symbols3->GetSymbolEntriesByOffset( + addr, + 0, + &arrSymbols[0], + NULL, + (ULONG)arrSymbols.size(), + NULL); + if (SUCCEEDED(hres)) + return RemoveSyntheticSymbols(arrSymbols); + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////////// + +static void DeleteSynSymbolsForModule( + const std::pair &synSymbolsForModule +) +{ + DEBUG_MODULE_PARAMETERS dbgModuleParameters; + HRESULT hres = dbgExt->symbols->GetModuleParameters( + 1, + const_cast(&synSymbolsForModule.first.m_base), + 0, + &dbgModuleParameters); + if ( FAILED( hres ) ) + return; + ModuleInfo gettedModuleInfo(dbgModuleParameters); + if (gettedModuleInfo == synSymbolsForModule.first) + { + // no clear - global map will be cleared on exit + SynSymbolsForModule::const_iterator itSynSymbol = + synSymbolsForModule.second.begin(); + while (itSynSymbol != synSymbolsForModule.second.end()) + { + RemoveSynSymbolsByAddress( + gettedModuleInfo.m_base + itSynSymbol->first); + ++itSynSymbol; + } + } +} + +///////////////////////////////////////////////////////////////////////////////// + +void delAllSyntheticSymbols() +{ + try + { + _SynSymbolsMapScopedLock(); + + for_each( + g_SyntheticSymbolMap.begin(), + g_SyntheticSymbolMap.end(), + DeleteSynSymbolsForModule); + g_SyntheticSymbolMap.clear(); + } + catch( std::exception &e ) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() ); + } + catch(...) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); + } +} + +///////////////////////////////////////////////////////////////////////////////// + +void delAllSyntheticSymbolsForModule( + const ModuleInfo &moduleInfo +) +{ + try + { + _SynSymbolsMapScopedLock(); + + SynSymbolsMap::iterator itSynSymbols = + g_SyntheticSymbolMap.find(moduleInfo); + if (itSynSymbols != g_SyntheticSymbolMap.end()) + { + std::pair synSymbolsForModule( + moduleInfo, itSynSymbols->second); + DeleteSynSymbolsForModule(synSymbolsForModule); + g_SyntheticSymbolMap.erase(itSynSymbols); + } + } + catch( std::exception &e ) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() ); + } + catch(...) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); + } +} + +///////////////////////////////////////////////////////////////////////////////// + +ULONG delSyntheticSymbolForModuleNoLock( + ULONG64 offset, + const ModuleInfo &moduleInfo +) +{ + SynSymbolsMap::iterator itSynSymbols = + g_SyntheticSymbolMap.find(moduleInfo); + if (itSynSymbols != g_SyntheticSymbolMap.end()) + { + offset = addr64(offset); + SynSymbolsForModule::iterator itSynSymbol = + itSynSymbols->second.find( offset ); + if (itSynSymbol != itSynSymbols->second.end()) + { + ULONG nResult = + RemoveSynSymbolsByAddress(moduleInfo.m_base + offset); + itSynSymbols->second.erase(itSynSymbol); + return nResult; + } + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////////// + +ULONG delSyntheticSymbol( + ULONG64 addr +) +{ + try + { + // query module information + addr = addr64(addr); + ULONG64 ptrModuleBase; + HRESULT hres = + dbgExt->symbols->GetModuleByOffset(addr, 0, NULL, &ptrModuleBase); + if ( SUCCEEDED(hres) ) + { + DEBUG_MODULE_PARAMETERS dbgModuleParameters; + hres = + dbgExt->symbols->GetModuleParameters( + 1, + &ptrModuleBase, + 0, + &dbgModuleParameters); + if ( SUCCEEDED(hres) ) + { + _SynSymbolsMapScopedLock(); + + ModuleInfo moduleInfo(dbgModuleParameters); + return + delSyntheticSymbolForModuleNoLock( + addr - moduleInfo.m_base, + moduleInfo); + } + } + } + catch( std::exception &e ) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() ); + } + catch(...) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); + } + + return 0; +} + +///////////////////////////////////////////////////////////////////////////////// + +ULONG delSyntheticSymbolForModule( + ULONG64 offset, + const ModuleInfo &moduleInfo +) +{ + try + { + _SynSymbolsMapScopedLock(); + return delSyntheticSymbolForModuleNoLock(offset, moduleInfo); + } + catch( std::exception &e ) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() ); + } + catch(...) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); + } + + return 0; +} + +///////////////////////////////////////////////////////////////////////////////// + +// remove synthetic symbols from global map +inline void RemoveSyntheticSymbolsFromMap( + const std::vector &arrSymbols +) +{ + for (ULONG i = 0; i < arrSymbols.size(); ++i) + { + DEBUG_SYMBOL_ENTRY dbgSymbolEntry; + HRESULT hres = dbgExt->symbols3->GetSymbolEntryInformation( + const_cast(&arrSymbols[i]), + &dbgSymbolEntry); + if (FAILED(hres)) + continue; + + DEBUG_MODULE_PARAMETERS dbgModuleParameters; + hres = dbgExt->symbols->GetModuleParameters( + 1, + &dbgSymbolEntry.ModuleBase, + 0, + &dbgModuleParameters); + if (FAILED(hres)) + continue; + + ModuleInfo moduleInfo(dbgModuleParameters); + SynSymbolsMap::iterator itSynSymbols = + g_SyntheticSymbolMap.find(moduleInfo); + if (itSynSymbols != g_SyntheticSymbolMap.end()) + { + ULONG64 offset = dbgSymbolEntry.Offset - dbgSymbolEntry.ModuleBase; + SynSymbolsForModule::iterator itSynSymbol = + itSynSymbols->second.find( offset ); + if (itSynSymbol != itSynSymbols->second.end()) + itSynSymbols->second.erase(itSynSymbol); + } + } +} + +///////////////////////////////////////////////////////////////////////////////// + +ULONG delSyntheticSymbolsMask( + const std::string &moduleName, + const std::string &symName +) +{ + ULONG nResult = 0; + + try + { + std::string symMask = moduleName + "!" + symName; + ULONG nEntries = 0; + dbgExt->symbols3->GetSymbolEntriesByName( + symMask.c_str(), + 0, + NULL, + 0, + &nEntries); + if (nEntries) + { + std::vector arrSymbols(nEntries); + HRESULT hres = dbgExt->symbols3->GetSymbolEntriesByName( + symMask.c_str(), + 0, + &arrSymbols[0], + (ULONG)arrSymbols.size(), + NULL); + if (FAILED(hres)) + throw DbgException( "call IDebugSymbol3::GetSymbolEntriesByOffset(...) failed" ); + + { + _SynSymbolsMapScopedLock(); + RemoveSyntheticSymbolsFromMap(arrSymbols); + } + + return RemoveSyntheticSymbols(arrSymbols); + } + } + catch( std::exception &e ) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() ); + } + catch(...) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); + } + + return nResult; +} + +///////////////////////////////////////////////////////////////////////////////// + +static void restoreSyntheticSymbolForModuleNoLock( + const ModuleInfo &moduleInfo, + IDebugSymbols3 *symbols3 +) +{ + SynSymbolsMap::const_iterator itSynSymbols = + g_SyntheticSymbolMap.find( moduleInfo ); + if (itSynSymbols != g_SyntheticSymbolMap.end()) + { + SynSymbolsForModule::const_iterator itSynSymbol = + itSynSymbols->second.begin(); + while (itSynSymbol != itSynSymbols->second.end()) + { + DEBUG_MODULE_AND_ID dbgModuleAndId; + symbols3->AddSyntheticSymbol( + moduleInfo.m_base + itSynSymbol->first, + itSynSymbol->second.m_size, + itSynSymbol->second.m_name.c_str(), + DEBUG_ADDSYNTHSYM_DEFAULT, + &dbgModuleAndId); + + ++itSynSymbol; + } + } +} + +///////////////////////////////////////////////////////////////////////////////// + +void restoreSyntheticSymbolForModule( + const ModuleInfo &moduleInfo, + IDebugSymbols3 *symbols3 +) +{ + _SynSymbolsMapScopedLock(); + + // see (**1) + if (!g_SyntheticSymbolMap.m_nRestoreAllModulesThread) + restoreSyntheticSymbolForModuleNoLock(moduleInfo, symbols3); +} + +///////////////////////////////////////////////////////////////////////////////// + +void restoreSyntheticSymbolForAllModules( + IDebugSymbols *symbols, + IDebugSymbols3 *symbols3 +) +{ + try + { + _SynSymbolsMapScopedLock(); + + // see (**1) + if (!g_SyntheticSymbolMap.m_nRestoreAllModulesThread) + { + ScopedAllModulesThread scopedAllModulesThread; + + ULONG nLoaded; + ULONG nUnloaded; + + HRESULT hres = symbols->GetNumberModules(&nLoaded, &nUnloaded); + if (SUCCEEDED(hres) && (nLoaded || nUnloaded)) + { + std::vector arrModules(nLoaded + nUnloaded); + hres = + symbols->GetModuleParameters( + (ULONG)arrModules.size(), + NULL, + 0, + &arrModules[0]); + if (SUCCEEDED(hres)) + { + for (ULONG i = 0; i < arrModules.size(); ++i) + { + ModuleInfo moduleInfo(arrModules[i]); + restoreSyntheticSymbolForModuleNoLock(moduleInfo, symbols3); + } + } + } + } + } + catch (...) + { + } +} + +///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgsynsym.h b/pykd/dbgsynsym.h new file mode 100644 index 0000000..852d746 --- /dev/null +++ b/pykd/dbgsynsym.h @@ -0,0 +1,61 @@ + +#pragma once + +///////////////////////////////////////////////////////////////////////////////// +// Global functions + +bool addSyntheticSymbol( + ULONG64 addr, + ULONG size, + const std::string &symName +); + +void delAllSyntheticSymbols(); + +ULONG delSyntheticSymbol( + ULONG64 addr +); + +ULONG delSyntheticSymbolsMask( + const std::string &moduleName, + const std::string &symName +); + +///////////////////////////////////////////////////////////////////////////////// +// Functions for dbgModuleClass + +ULONG64 getSyntheticSymbol( + const ModuleInfo &moduleInfo, + const std::string &symName +); + +bool addSyntheticSymbolForModule( + ULONG64 offset, + ULONG size, + const std::string &symName, + const ModuleInfo &moduleInfo +); + +ULONG delSyntheticSymbolForModule( + ULONG64 offset, + const ModuleInfo &moduleInfo +); + +void delAllSyntheticSymbolsForModule( + const ModuleInfo &moduleInfo +); + +///////////////////////////////////////////////////////////////////////////////// +// External callbacks + +void restoreSyntheticSymbolForModule( + const ModuleInfo &moduleInfo, + IDebugSymbols3 *symbols3 +); + +void restoreSyntheticSymbolForAllModules( + IDebugSymbols *symbols, + IDebugSymbols3 *symbols3 +); + +///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgsystem.cpp b/pykd/dbgsystem.cpp index bd2c55d..e793ceb 100644 --- a/pykd/dbgsystem.cpp +++ b/pykd/dbgsystem.cpp @@ -133,7 +133,7 @@ reloadModule( const char * moduleName ) hres = dbgExt->symbols->Reload( moduleName ); //if ( FAILED( hres ) ) - // throw DbgException( "IDebugSymbol::Reload failed" ); + // throw DbgException( "IDebugSymbol::Reload failed" ); } catch( std::exception &e ) { diff --git a/pykd/dbgtype.cpp b/pykd/dbgtype.cpp index 75e5c77..91706fd 100644 --- a/pykd/dbgtype.cpp +++ b/pykd/dbgtype.cpp @@ -550,11 +550,19 @@ typedVarClass::printField(const TypeInfo::TypeField &field, stringstream &sstr) else if ( field.type.name() == "unsigned short*" ) { wchar_t wbuf[0x100]; - if ( loadWStrToBuffer( val, wbuf, sizeof(wbuf) ) ) + if ( loadWStrToBuffer( val, wbuf, sizeof(wbuf) ) ) { char mbBuf[0x100] = { 0 }; - WideCharToMultiByte( CP_ACP, 0, wbuf, wcslen(wbuf)+1, mbBuf, sizeof(mbBuf), NULL, NULL ); + WideCharToMultiByte( + CP_ACP, + 0, + wbuf, + (ULONG)wcslen(wbuf) + 1, + mbBuf, + sizeof(mbBuf), + NULL, + NULL); sstr << " (" << mbBuf << " )"; } diff --git a/pykd/dbgtype.h b/pykd/dbgtype.h index c648f96..eb9eff2 100644 --- a/pykd/dbgtype.h +++ b/pykd/dbgtype.h @@ -4,9 +4,6 @@ #include #include -#include -#include - #include "dbgmem.h" ///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/pykd.vcproj b/pykd/pykd.vcproj index 7544c4a..24cf619 100644 --- a/pykd/pykd.vcproj +++ b/pykd/pykd.vcproj @@ -1,7 +1,7 @@ + + @@ -400,6 +404,10 @@ RelativePath=".\dbgsym.cpp" > + + @@ -466,6 +474,10 @@ RelativePath=".\dbgdump.h" > + + @@ -510,6 +522,10 @@ RelativePath=".\dbgsym.h" > + + @@ -537,10 +553,6 @@ > - - diff --git a/pykd/stdafx.h b/pykd/stdafx.h index d5d3fc6..8e6babf 100644 --- a/pykd/stdafx.h +++ b/pykd/stdafx.h @@ -38,4 +38,11 @@ #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 +#include +#pragma warning(pop) + // TODO: reference additional headers your program requires here