diff --git a/pykd/dbgeventcb.cpp b/pykd/dbgeventcb.cpp index 8c8b547..dbb065a 100644 --- a/pykd/dbgeventcb.cpp +++ b/pykd/dbgeventcb.cpp @@ -10,11 +10,14 @@ ///////////////////////////////////////////////////////////////////////////////// -DbgEventCallbacks dbgEventCallbacks; +DbgEventCallbacks *dbgEventCallbacks = NULL; ///////////////////////////////////////////////////////////////////////////////// -HRESULT DbgEventCallbacks::Register() +DbgEventCallbacks::DbgEventCallbacks() + : m_ReferenceCount(1) + , m_dbgClient(NULL) + , m_dbgSymbols3(NULL) { HRESULT hres; try @@ -26,22 +29,12 @@ HRESULT DbgEventCallbacks::Register() if (FAILED(hres)) throw hres; - hres = m_dbgClient->QueryInterface( - __uuidof(IDebugSymbols), - reinterpret_cast(&m_dbgSymbols)); - if (FAILED(hres)) - throw hres; - hres = m_dbgClient->QueryInterface( __uuidof(IDebugSymbols3), reinterpret_cast(&m_dbgSymbols3)); 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; @@ -57,9 +50,10 @@ HRESULT DbgEventCallbacks::Register() hres = S_FALSE; } if (S_OK != hres) + { Deregister(); - - return hres; + throw hres; + } } ///////////////////////////////////////////////////////////////////////////////// @@ -71,18 +65,32 @@ void DbgEventCallbacks::Deregister() m_dbgSymbols3->Release(); m_dbgSymbols3 = NULL; } - if (m_dbgSymbols) - { - m_dbgSymbols->Release(); - m_dbgSymbols = NULL; - } if (m_dbgClient) { - m_dbgClient->SetEventCallbacks(m_prevCallbacks); - m_dbgClient->Release(); m_dbgClient = NULL; } + Release(); +} + +///////////////////////////////////////////////////////////////////////////////// + +ULONG DbgEventCallbacks::AddRef() +{ + return InterlockedIncrement(&m_ReferenceCount); +} + +///////////////////////////////////////////////////////////////////////////////// + +ULONG DbgEventCallbacks::Release() +{ + ULONG nResult = InterlockedDecrement(&m_ReferenceCount); + if (!nResult) + { + dbgEventCallbacks = NULL; + delete this; + } + return nResult; } ///////////////////////////////////////////////////////////////////////////////// @@ -94,136 +102,6 @@ HRESULT DbgEventCallbacks::GetInterestMask( *Mask = DEBUG_EVENT_CHANGE_SYMBOL_STATE; return S_OK; } -///////////////////////////////////////////////////////////////////////////////// - -HRESULT DbgEventCallbacks::Breakpoint( - __in PDEBUG_BREAKPOINT /* Bp */ -) -{ - return DEBUG_STATUS_IGNORE_EVENT; -} - -///////////////////////////////////////////////////////////////////////////////// - -HRESULT DbgEventCallbacks::Exception( - __in PEXCEPTION_RECORD64 /* Exception */, - __in ULONG /* FirstChance */ -) -{ - return DEBUG_STATUS_IGNORE_EVENT; -} - -///////////////////////////////////////////////////////////////////////////////// - -HRESULT DbgEventCallbacks::CreateThread( - __in ULONG64 /* Handle */, - __in ULONG64 /* DataOffset */, - __in ULONG64 /* StartOffset */ -) -{ - return DEBUG_STATUS_IGNORE_EVENT; -} - -///////////////////////////////////////////////////////////////////////////////// - -HRESULT DbgEventCallbacks::ExitThread( - __in ULONG /* ExitCode */ -) -{ - return DEBUG_STATUS_IGNORE_EVENT; -} - -///////////////////////////////////////////////////////////////////////////////// - -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; -} - -///////////////////////////////////////////////////////////////////////////////// - -HRESULT DbgEventCallbacks::ExitProcess( - __in ULONG /* ExitCode */ -) -{ - return DEBUG_STATUS_IGNORE_EVENT; -} - -///////////////////////////////////////////////////////////////////////////////// - -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; -} - -///////////////////////////////////////////////////////////////////////////////// - -HRESULT DbgEventCallbacks::UnloadModule( - __in_opt PCSTR /* ImageBaseName */, - __in ULONG64 /* BaseOffset */ -) -{ - return DEBUG_STATUS_IGNORE_EVENT; -} - -///////////////////////////////////////////////////////////////////////////////// - -HRESULT DbgEventCallbacks::SystemError( - __in ULONG /* Error */, - __in ULONG /* Level */ -) -{ - return DEBUG_STATUS_IGNORE_EVENT; -} - -///////////////////////////////////////////////////////////////////////////////// - -HRESULT DbgEventCallbacks::SessionStatus( - __in ULONG /* Status */ -) -{ - return DEBUG_STATUS_IGNORE_EVENT; -} - -///////////////////////////////////////////////////////////////////////////////// - -HRESULT DbgEventCallbacks::ChangeDebuggeeState( - __in ULONG /* Flags */, - __in ULONG64 /* Argument */ -) -{ - return DEBUG_STATUS_IGNORE_EVENT; -} - -///////////////////////////////////////////////////////////////////////////////// - -HRESULT DbgEventCallbacks::ChangeEngineState( - __in ULONG /* Flags */, - __in ULONG64 /* Argument */ -) -{ - return DEBUG_STATUS_IGNORE_EVENT; -} ///////////////////////////////////////////////////////////////////////////////// @@ -238,11 +116,11 @@ HRESULT DbgEventCallbacks::ChangeSymbolState( return doSymbolsLoaded(Argument); // f.e. is case ".reload /f image.exe", if for image.exe no symbols - restoreSyntheticSymbolForAllModules(m_dbgSymbols, m_dbgSymbols3); + restoreSyntheticSymbolForAllModules(m_dbgSymbols3); return S_OK; } - return DEBUG_STATUS_IGNORE_EVENT; + return S_OK; } ///////////////////////////////////////////////////////////////////////////////// @@ -254,7 +132,7 @@ HRESULT DbgEventCallbacks::doSymbolsLoaded( try { DEBUG_MODULE_PARAMETERS dbgModuleParameters; - HRESULT hres = m_dbgSymbols->GetModuleParameters( + HRESULT hres = m_dbgSymbols3->GetModuleParameters( 1, &moduleBase, 0, diff --git a/pykd/dbgeventcb.h b/pykd/dbgeventcb.h index f3d2970..eb9863f 100644 --- a/pykd/dbgeventcb.h +++ b/pykd/dbgeventcb.h @@ -2,24 +2,12 @@ #pragma once // monitoring and processing debug events -class DbgEventCallbacks : public IDebugEventCallbacks +class DbgEventCallbacks : public DebugBaseEventCallbacks { public: - DbgEventCallbacks() - : m_dbgClient(NULL) - , m_prevCallbacks(NULL) - , m_dbgSymbols(NULL) - , m_dbgSymbols3(NULL) - { - } - ~DbgEventCallbacks() - { - Deregister(); - } - - // [de]register debug event handler - HRESULT Register(); + // may generate HRESULT exception if not registered + DbgEventCallbacks(); void Deregister(); private: @@ -27,18 +15,8 @@ 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; } + STDMETHOD_(ULONG, AddRef)(); + STDMETHOD_(ULONG, Release)(); ///////////////////////////////////////////////////////////////////////////////// // IDebugEventCallbacks interface implementation @@ -47,77 +25,6 @@ private: __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 @@ -131,15 +38,15 @@ private: ///////////////////////////////////////////////////////////////////////////////// + volatile LONG m_ReferenceCount; + IDebugClient *m_dbgClient; - IDebugEventCallbacks *m_prevCallbacks; - IDebugSymbols *m_dbgSymbols; IDebugSymbols3 *m_dbgSymbols3; }; ///////////////////////////////////////////////////////////////////////////////// // global singleton -extern DbgEventCallbacks dbgEventCallbacks; +extern DbgEventCallbacks *dbgEventCallbacks; ///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 84f1410..1f81a92 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -219,20 +219,20 @@ DebugExtensionInitialize( windbgGlobalSession = new WindbgGlobalSession(); - setDbgSessionStarted(); - - return S_OK; + return setDbgSessionStarted(); } - - + + VOID CALLBACK DebugExtensionUninitialize() { + stopDbgEventMonotoring(); + delete windbgGlobalSession; windbgGlobalSession = NULL; - Py_Finalize(); + Py_Finalize(); } diff --git a/pykd/dbgsession.h b/pykd/dbgsession.h index 8fb2d7f..21a4d16 100644 --- a/pykd/dbgsession.h +++ b/pykd/dbgsession.h @@ -6,11 +6,32 @@ dbgCreateSession(); extern bool dbgSessionStarted; -inline void setDbgSessionStarted() +inline void stopDbgEventMonotoring() { - dbgEventCallbacks.Register(); + if (dbgEventCallbacks) + dbgEventCallbacks->Deregister(); +} - dbgSessionStarted = true; +inline HRESULT setDbgSessionStarted() +{ + HRESULT hres; + try + { + stopDbgEventMonotoring(); + dbgEventCallbacks = new DbgEventCallbacks; + hres = S_OK; + } + catch (HRESULT _hres) + { + hres = _hres; + } + catch (...) + { + hres = E_OUTOFMEMORY; + } + if (SUCCEEDED(hres)) + dbgSessionStarted = true; + return hres; } bool diff --git a/pykd/dbgsynsym.cpp b/pykd/dbgsynsym.cpp index 2f4b1ab..d0d98ea 100644 --- a/pykd/dbgsynsym.cpp +++ b/pykd/dbgsynsym.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -51,41 +52,24 @@ typedef std::map SynSymbolsMap; // synchro-object for global synthetic symbols map typedef boost::interprocess::interprocess_recursive_mutex SynSymbolsMapLockType; +typedef boost::interprocess::interprocess_mutex SynSymbolsMapLockWriteType; // scoped lock synchro-object for global synthetic symbols map typedef boost::interprocess::scoped_lock SynSymbolsMapScopedLock; +typedef boost::interprocess::scoped_lock SynSymbolsMapScopedLockWrite; 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; + SynSymbolsMapLockWriteType m_LockWrite; }g_SyntheticSymbolMap; #define _SynSymbolsMapScopedLock() \ SynSymbolsMapScopedLock _lock(g_SyntheticSymbolMap.m_Lock) +#define _SynSymbolsMapScopedLockWrite() \ + _SynSymbolsMapScopedLock(); \ + SynSymbolsMapScopedLockWrite _lockw(g_SyntheticSymbolMap.m_LockWrite) -// (**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; -}; ///////////////////////////////////////////////////////////////////////////////// @@ -122,7 +106,7 @@ bool addSyntheticSymbol( throw DbgException( "call IDebugSymbol3::GetModuleParameters(...) failed" ); } - _SynSymbolsMapScopedLock(); + _SynSymbolsMapScopedLockWrite(); ModuleInfo moduleInfo(dbgModuleParameters); SynSymbolsForModule &mapSynSymbolsForModule = @@ -192,7 +176,7 @@ bool addSyntheticSymbolForModule( } } - _SynSymbolsMapScopedLock(); + _SynSymbolsMapScopedLockWrite(); SynSymbolsForModule &mapSynSymbolsForModule = g_SyntheticSymbolMap[moduleInfo]; @@ -354,7 +338,7 @@ void delAllSyntheticSymbols() { try { - _SynSymbolsMapScopedLock(); + _SynSymbolsMapScopedLockWrite(); for_each( g_SyntheticSymbolMap.begin(), @@ -380,7 +364,7 @@ void delAllSyntheticSymbolsForModule( { try { - _SynSymbolsMapScopedLock(); + _SynSymbolsMapScopedLockWrite(); SynSymbolsMap::iterator itSynSymbols = g_SyntheticSymbolMap.find(moduleInfo); @@ -451,7 +435,7 @@ ULONG delSyntheticSymbol( &dbgModuleParameters); if ( SUCCEEDED(hres) ) { - _SynSymbolsMapScopedLock(); + _SynSymbolsMapScopedLockWrite(); ModuleInfo moduleInfo(dbgModuleParameters); return @@ -482,7 +466,7 @@ ULONG delSyntheticSymbolForModule( { try { - _SynSymbolsMapScopedLock(); + _SynSymbolsMapScopedLockWrite(); return delSyntheticSymbolForModuleNoLock(offset, moduleInfo); } catch( std::exception &e ) @@ -568,7 +552,7 @@ ULONG delSyntheticSymbolsMask( throw DbgException( "call IDebugSymbol3::GetSymbolEntriesByOffset(...) failed" ); { - _SynSymbolsMapScopedLock(); + _SynSymbolsMapScopedLockWrite(); RemoveSyntheticSymbolsFromMap(arrSymbols); } @@ -625,46 +609,37 @@ void restoreSyntheticSymbolForModule( _SynSymbolsMapScopedLock(); // see (**1) - if (!g_SyntheticSymbolMap.m_nRestoreAllModulesThread) - restoreSyntheticSymbolForModuleNoLock(moduleInfo, symbols3); + restoreSyntheticSymbolForModuleNoLock(moduleInfo, symbols3); } ///////////////////////////////////////////////////////////////////////////////// void restoreSyntheticSymbolForAllModules( - IDebugSymbols *symbols, IDebugSymbols3 *symbols3 ) { try { _SynSymbolsMapScopedLock(); + ULONG nLoaded; + ULONG nUnloaded; - // see (**1) - if (!g_SyntheticSymbolMap.m_nRestoreAllModulesThread) + HRESULT hres = symbols3->GetNumberModules(&nLoaded, &nUnloaded); + if (SUCCEEDED(hres) && (nLoaded || nUnloaded)) { - ScopedAllModulesThread scopedAllModulesThread; - - ULONG nLoaded; - ULONG nUnloaded; - - HRESULT hres = symbols->GetNumberModules(&nLoaded, &nUnloaded); - if (SUCCEEDED(hres) && (nLoaded || nUnloaded)) + std::vector arrModules(nLoaded + nUnloaded); + hres = + symbols3->GetModuleParameters( + (ULONG)arrModules.size(), + NULL, + 0, + &arrModules[0]); + if (SUCCEEDED(hres)) { - 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) { - for (ULONG i = 0; i < arrModules.size(); ++i) - { - ModuleInfo moduleInfo(arrModules[i]); - restoreSyntheticSymbolForModuleNoLock(moduleInfo, symbols3); - } + ModuleInfo moduleInfo(arrModules[i]); + restoreSyntheticSymbolForModuleNoLock(moduleInfo, symbols3); } } } diff --git a/pykd/dbgsynsym.h b/pykd/dbgsynsym.h index 852d746..4708d6d 100644 --- a/pykd/dbgsynsym.h +++ b/pykd/dbgsynsym.h @@ -54,7 +54,6 @@ void restoreSyntheticSymbolForModule( ); void restoreSyntheticSymbolForAllModules( - IDebugSymbols *symbols, IDebugSymbols3 *symbols3 );