In certain circumstances unmarshalling an object stream from the RunningObjectTable can cause the unmarshalling routines to interrogate the same table (maybe to resolve a dependant object?) in a different thread causing a deadlock while getting the critical section lock. Leaving the Critical Section before unmarshalling the object stream solve this problem. Visual Studio 2019 deadlock on start without this.
I'm not sure how to test this properly. Also add debug info for this critical section so it show a significant name in the log.
Signed-off-by: Lorenzo Ferrillo lorenzofersteam@live.it
-- v2: ole32: Add debug info to RunningObjectTable critical section ole32: Leave the RunningObjectTable Critical Section before umarshalling object
From: Lorenzo Ferrillo lorenzofersteam@live.it
Sometimes umarshalling an object from the RunningObjectTable can cause the routine to access the table back inside another thread, causing a deadlock. Visual Studio 2019 is an example of this behaviour.
Signed-off-by: Lorenzo Ferrillo lorenzofersteam@live.it --- dlls/ole32/moniker.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/ole32/moniker.c b/dlls/ole32/moniker.c index ec026758b2f..06a2ef8de9c 100644 --- a/dlls/ole32/moniker.c +++ b/dlls/ole32/moniker.c @@ -541,13 +541,14 @@ RunningObjectTableImpl_GetObject( IRunningObjectTable* iface, { IStream *pStream; hr = create_stream_on_mip_ro(rot_entry->object, &pStream); + LeaveCriticalSection(&This->lock); + if (hr == S_OK) { hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)ppunkObject); IStream_Release(pStream); }
- LeaveCriticalSection(&This->lock); HeapFree(GetProcessHeap(), 0, moniker_data);
return hr;
From: Lorenzo Ferrillo lorenzofersteam@live.it
So it's possible to easily debug deadlocks involving the Internal ROT object
Signed-off-by: Lorenzo Ferrillo lorenzofersteam@live.it --- dlls/ole32/moniker.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/dlls/ole32/moniker.c b/dlls/ole32/moniker.c index 06a2ef8de9c..a56039d05b6 100644 --- a/dlls/ole32/moniker.c +++ b/dlls/ole32/moniker.c @@ -707,10 +707,20 @@ static const IRunningObjectTableVtbl VT_RunningObjectTableImpl = RunningObjectTableImpl_EnumRunning };
+ +static RunningObjectTableImpl rot; + +static RTL_CRITICAL_SECTION_DEBUG critsect_debug = +{ + 0, 0, &rot.lock, + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": RunningObjectTable_section") } +}; + static RunningObjectTableImpl rot = { .IRunningObjectTable_iface.lpVtbl = &VT_RunningObjectTableImpl, - .lock.LockCount = -1, + .lock = { &critsect_debug, -1, 0, 0, 0, 0 }, .rot = LIST_INIT(rot.rot), };