[~] 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
This commit is contained in:
SND\EreTIk_cp 2011-03-02 18:37:42 +00:00
parent 364da2b716
commit b73ccc1a37
6 changed files with 100 additions and 320 deletions

View File

@ -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; HRESULT hres;
try try
@ -26,22 +29,12 @@ HRESULT DbgEventCallbacks::Register()
if (FAILED(hres)) if (FAILED(hres))
throw hres; throw hres;
hres = m_dbgClient->QueryInterface(
__uuidof(IDebugSymbols),
reinterpret_cast<PVOID *>(&m_dbgSymbols));
if (FAILED(hres))
throw hres;
hres = m_dbgClient->QueryInterface( hres = m_dbgClient->QueryInterface(
__uuidof(IDebugSymbols3), __uuidof(IDebugSymbols3),
reinterpret_cast<PVOID *>(&m_dbgSymbols3)); reinterpret_cast<PVOID *>(&m_dbgSymbols3));
if (FAILED(hres)) if (FAILED(hres))
throw hres; throw hres;
hres = m_dbgClient->GetEventCallbacks(&m_prevCallbacks);
if (FAILED(hres))
throw hres;
hres = m_dbgClient->SetEventCallbacks(this); hres = m_dbgClient->SetEventCallbacks(this);
if (FAILED(hres)) if (FAILED(hres))
throw hres; throw hres;
@ -57,9 +50,10 @@ HRESULT DbgEventCallbacks::Register()
hres = S_FALSE; hres = S_FALSE;
} }
if (S_OK != hres) if (S_OK != hres)
{
Deregister(); Deregister();
throw hres;
return hres; }
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
@ -71,18 +65,32 @@ void DbgEventCallbacks::Deregister()
m_dbgSymbols3->Release(); m_dbgSymbols3->Release();
m_dbgSymbols3 = NULL; m_dbgSymbols3 = NULL;
} }
if (m_dbgSymbols)
{
m_dbgSymbols->Release();
m_dbgSymbols = NULL;
}
if (m_dbgClient) if (m_dbgClient)
{ {
m_dbgClient->SetEventCallbacks(m_prevCallbacks);
m_dbgClient->Release(); m_dbgClient->Release();
m_dbgClient = NULL; 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; *Mask = DEBUG_EVENT_CHANGE_SYMBOL_STATE;
return S_OK; 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); return doSymbolsLoaded(Argument);
// f.e. is case ".reload /f image.exe", if for image.exe no symbols // 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 S_OK;
} }
return DEBUG_STATUS_IGNORE_EVENT; return S_OK;
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
@ -254,7 +132,7 @@ HRESULT DbgEventCallbacks::doSymbolsLoaded(
try try
{ {
DEBUG_MODULE_PARAMETERS dbgModuleParameters; DEBUG_MODULE_PARAMETERS dbgModuleParameters;
HRESULT hres = m_dbgSymbols->GetModuleParameters( HRESULT hres = m_dbgSymbols3->GetModuleParameters(
1, 1,
&moduleBase, &moduleBase,
0, 0,

View File

@ -2,24 +2,12 @@
#pragma once #pragma once
// monitoring and processing debug events // monitoring and processing debug events
class DbgEventCallbacks : public IDebugEventCallbacks class DbgEventCallbacks : public DebugBaseEventCallbacks
{ {
public: public:
DbgEventCallbacks() // may generate HRESULT exception if not registered
: m_dbgClient(NULL) DbgEventCallbacks();
, m_prevCallbacks(NULL)
, m_dbgSymbols(NULL)
, m_dbgSymbols3(NULL)
{
}
~DbgEventCallbacks()
{
Deregister();
}
// [de]register debug event handler
HRESULT Register();
void Deregister(); void Deregister();
private: private:
@ -27,18 +15,8 @@ private:
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
// IUnknown interface implementation // IUnknown interface implementation
STDMETHOD(QueryInterface)(__in REFIID InterfaceId, __out PVOID *Interface) STDMETHOD_(ULONG, AddRef)();
{ STDMETHOD_(ULONG, Release)();
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 // IDebugEventCallbacks interface implementation
@ -47,77 +25,6 @@ private:
__out PULONG Mask __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)( STDMETHOD(ChangeSymbolState)(
__in ULONG Flags, __in ULONG Flags,
__in ULONG64 Argument __in ULONG64 Argument
@ -131,15 +38,15 @@ private:
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
volatile LONG m_ReferenceCount;
IDebugClient *m_dbgClient; IDebugClient *m_dbgClient;
IDebugEventCallbacks *m_prevCallbacks;
IDebugSymbols *m_dbgSymbols;
IDebugSymbols3 *m_dbgSymbols3; IDebugSymbols3 *m_dbgSymbols3;
}; };
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
// global singleton // global singleton
extern DbgEventCallbacks dbgEventCallbacks; extern DbgEventCallbacks *dbgEventCallbacks;
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////

View File

@ -219,20 +219,20 @@ DebugExtensionInitialize(
windbgGlobalSession = new WindbgGlobalSession(); windbgGlobalSession = new WindbgGlobalSession();
setDbgSessionStarted(); return setDbgSessionStarted();
return S_OK;
} }
VOID VOID
CALLBACK CALLBACK
DebugExtensionUninitialize() DebugExtensionUninitialize()
{ {
stopDbgEventMonotoring();
delete windbgGlobalSession; delete windbgGlobalSession;
windbgGlobalSession = NULL; windbgGlobalSession = NULL;
Py_Finalize(); Py_Finalize();
} }

View File

@ -6,11 +6,32 @@ dbgCreateSession();
extern extern
bool dbgSessionStarted; 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 bool

View File

@ -2,6 +2,7 @@
#include <boost/interprocess/sync/scoped_lock.hpp> #include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp> #include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <vector> #include <vector>
#include <list> #include <list>
@ -51,41 +52,24 @@ typedef std::map<ModuleInfo, SynSymbolsForModule> SynSymbolsMap;
// synchro-object for global synthetic symbols map // synchro-object for global synthetic symbols map
typedef boost::interprocess::interprocess_recursive_mutex SynSymbolsMapLockType; typedef boost::interprocess::interprocess_recursive_mutex SynSymbolsMapLockType;
typedef boost::interprocess::interprocess_mutex SynSymbolsMapLockWriteType;
// scoped lock synchro-object for global synthetic symbols map // scoped lock synchro-object for global synthetic symbols map
typedef boost::interprocess::scoped_lock<SynSymbolsMapLockType> SynSymbolsMapScopedLock; typedef boost::interprocess::scoped_lock<SynSymbolsMapLockType> SynSymbolsMapScopedLock;
typedef boost::interprocess::scoped_lock<SynSymbolsMapLockWriteType> SynSymbolsMapScopedLockWrite;
static struct _GlobalSyntheticSymbolMap : public SynSymbolsMap static struct _GlobalSyntheticSymbolMap : public SynSymbolsMap
{ {
_GlobalSyntheticSymbolMap() : m_nRestoreAllModulesThread(0) {}
SynSymbolsMapLockType m_Lock; SynSymbolsMapLockType m_Lock;
SynSymbolsMapLockWriteType m_LockWrite;
// (**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; }g_SyntheticSymbolMap;
#define _SynSymbolsMapScopedLock() \ #define _SynSymbolsMapScopedLock() \
SynSymbolsMapScopedLock _lock(g_SyntheticSymbolMap.m_Lock) 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" ); throw DbgException( "call IDebugSymbol3::GetModuleParameters(...) failed" );
} }
_SynSymbolsMapScopedLock(); _SynSymbolsMapScopedLockWrite();
ModuleInfo moduleInfo(dbgModuleParameters); ModuleInfo moduleInfo(dbgModuleParameters);
SynSymbolsForModule &mapSynSymbolsForModule = SynSymbolsForModule &mapSynSymbolsForModule =
@ -192,7 +176,7 @@ bool addSyntheticSymbolForModule(
} }
} }
_SynSymbolsMapScopedLock(); _SynSymbolsMapScopedLockWrite();
SynSymbolsForModule &mapSynSymbolsForModule = SynSymbolsForModule &mapSynSymbolsForModule =
g_SyntheticSymbolMap[moduleInfo]; g_SyntheticSymbolMap[moduleInfo];
@ -354,7 +338,7 @@ void delAllSyntheticSymbols()
{ {
try try
{ {
_SynSymbolsMapScopedLock(); _SynSymbolsMapScopedLockWrite();
for_each( for_each(
g_SyntheticSymbolMap.begin(), g_SyntheticSymbolMap.begin(),
@ -380,7 +364,7 @@ void delAllSyntheticSymbolsForModule(
{ {
try try
{ {
_SynSymbolsMapScopedLock(); _SynSymbolsMapScopedLockWrite();
SynSymbolsMap::iterator itSynSymbols = SynSymbolsMap::iterator itSynSymbols =
g_SyntheticSymbolMap.find(moduleInfo); g_SyntheticSymbolMap.find(moduleInfo);
@ -451,7 +435,7 @@ ULONG delSyntheticSymbol(
&dbgModuleParameters); &dbgModuleParameters);
if ( SUCCEEDED(hres) ) if ( SUCCEEDED(hres) )
{ {
_SynSymbolsMapScopedLock(); _SynSymbolsMapScopedLockWrite();
ModuleInfo moduleInfo(dbgModuleParameters); ModuleInfo moduleInfo(dbgModuleParameters);
return return
@ -482,7 +466,7 @@ ULONG delSyntheticSymbolForModule(
{ {
try try
{ {
_SynSymbolsMapScopedLock(); _SynSymbolsMapScopedLockWrite();
return delSyntheticSymbolForModuleNoLock(offset, moduleInfo); return delSyntheticSymbolForModuleNoLock(offset, moduleInfo);
} }
catch( std::exception &e ) catch( std::exception &e )
@ -568,7 +552,7 @@ ULONG delSyntheticSymbolsMask(
throw DbgException( "call IDebugSymbol3::GetSymbolEntriesByOffset(...) failed" ); throw DbgException( "call IDebugSymbol3::GetSymbolEntriesByOffset(...) failed" );
{ {
_SynSymbolsMapScopedLock(); _SynSymbolsMapScopedLockWrite();
RemoveSyntheticSymbolsFromMap(arrSymbols); RemoveSyntheticSymbolsFromMap(arrSymbols);
} }
@ -625,46 +609,37 @@ void restoreSyntheticSymbolForModule(
_SynSymbolsMapScopedLock(); _SynSymbolsMapScopedLock();
// see (**1) // see (**1)
if (!g_SyntheticSymbolMap.m_nRestoreAllModulesThread) restoreSyntheticSymbolForModuleNoLock(moduleInfo, symbols3);
restoreSyntheticSymbolForModuleNoLock(moduleInfo, symbols3);
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
void restoreSyntheticSymbolForAllModules( void restoreSyntheticSymbolForAllModules(
IDebugSymbols *symbols,
IDebugSymbols3 *symbols3 IDebugSymbols3 *symbols3
) )
{ {
try try
{ {
_SynSymbolsMapScopedLock(); _SynSymbolsMapScopedLock();
ULONG nLoaded;
ULONG nUnloaded;
// see (**1) HRESULT hres = symbols3->GetNumberModules(&nLoaded, &nUnloaded);
if (!g_SyntheticSymbolMap.m_nRestoreAllModulesThread) if (SUCCEEDED(hres) && (nLoaded || nUnloaded))
{ {
ScopedAllModulesThread scopedAllModulesThread; std::vector<DEBUG_MODULE_PARAMETERS> arrModules(nLoaded + nUnloaded);
hres =
ULONG nLoaded; symbols3->GetModuleParameters(
ULONG nUnloaded; (ULONG)arrModules.size(),
NULL,
HRESULT hres = symbols->GetNumberModules(&nLoaded, &nUnloaded); 0,
if (SUCCEEDED(hres) && (nLoaded || nUnloaded)) &arrModules[0]);
if (SUCCEEDED(hres))
{ {
std::vector<DEBUG_MODULE_PARAMETERS> arrModules(nLoaded + nUnloaded); for (ULONG i = 0; i < arrModules.size(); ++i)
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);
ModuleInfo moduleInfo(arrModules[i]);
restoreSyntheticSymbolForModuleNoLock(moduleInfo, symbols3);
}
} }
} }
} }

View File

@ -54,7 +54,6 @@ void restoreSyntheticSymbolForModule(
); );
void restoreSyntheticSymbolForAllModules( void restoreSyntheticSymbolForAllModules(
IDebugSymbols *symbols,
IDebugSymbols3 *symbols3 IDebugSymbols3 *symbols3
); );