From b73ccc1a372edc35253aedc71a1aa1195141c012 Mon Sep 17 00:00:00 2001
From: "SND\\EreTIk_cp" <SND\EreTIk_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Wed, 2 Mar 2011 18:37:42 +0000
Subject: [PATCH] [~] dbgEventCallbacks moved to heap memory, add rererences
 [~] refactered syncronisation for map of synthetic symbols [~] refactering:
 events callbacks inherited from DebugBaseEventCallbacks now

git-svn-id: https://pykd.svn.codeplex.com/svn@62100 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/dbgeventcb.cpp | 186 ++++++++------------------------------------
 pykd/dbgeventcb.h   | 109 ++------------------------
 pykd/dbgext.cpp     |  12 +--
 pykd/dbgsession.h   |  27 ++++++-
 pykd/dbgsynsym.cpp  |  85 +++++++-------------
 pykd/dbgsynsym.h    |   1 -
 6 files changed, 100 insertions(+), 320 deletions(-)

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<PVOID *>(&m_dbgSymbols));
-        if (FAILED(hres))
-            throw hres;
-
         hres = m_dbgClient->QueryInterface(
             __uuidof(IDebugSymbols3),
             reinterpret_cast<PVOID *>(&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 <boost/interprocess/sync/scoped_lock.hpp>
 #include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
+#include <boost/interprocess/sync/interprocess_mutex.hpp>
 #include <vector>
 #include <list>
 
@@ -51,41 +52,24 @@ typedef std::map<ModuleInfo, SynSymbolsForModule> 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<SynSymbolsMapLockType> SynSymbolsMapScopedLock;
+typedef boost::interprocess::scoped_lock<SynSymbolsMapLockWriteType> 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<DEBUG_MODULE_PARAMETERS> arrModules(nLoaded + nUnloaded);
+            hres = 
+                symbols3->GetModuleParameters(
+                    (ULONG)arrModules.size(),
+                    NULL,
+                    0,
+                    &arrModules[0]);
+            if (SUCCEEDED(hres))
             {
-                std::vector<DEBUG_MODULE_PARAMETERS> 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
 );