epics-base / pva2pva

PV Access gateway/proxy and EPICS Process Database integration
https://epics-base.github.io/pva2pva/
Other
4 stars 13 forks source link

Potential race in dbNotify between callback and PVA worker #45

Open mdavidsaver opened 3 years ago

mdavidsaver commented 3 years ago

Valgrind flags an race for access to a processNotify struct between the callback thread used by dbNotify and the PVA server worker. My present scheme used the doneCallback to identify completion, but I see that the struct will still be accessed after this point by notifyCleanup().

My attempt at a quick fix ran into trouble with calling dbNotifyCancel() from a callback thread, which deadlocks.

As it stands, there is a chance of a crash if a remote client cancels/disconnects while an async PUT is in progress.

Thread 5 cbLow:
Invalid read of size 8
   at 0x4F1AE00: notifyCleanup (dbNotify.c:142)
   by 0x4F1B075: callDone (dbNotify.c:190)
   by 0x4F1B70A: notifyCallback (dbNotify.c:304)
   by 0x4F29F27: callbackTask (callback.c:223)
   by 0x5036642: start_routine (osdThread.c:418)
   by 0x55ACFA2: start_thread (pthread_create.c:486)
   by 0x54DD4CE: clone (clone.S:95)
 Address 0x5b81970 is 144 bytes inside a block of size 232 free'd
   at 0x483708B: operator delete(void*, unsigned long) (vg_replace_malloc.c:585)
   by 0x48EF13C: PDBSinglePut::~PDBSinglePut() (pdbsingle.cpp:350)
...
 Block was alloc'd at
   at 0x4835DEF: operator new(unsigned long) (vg_replace_malloc.c:334)
   by 0x48ED810: PDBSingleChannel::createChannelPut(std::shared_ptr<epics::pvAccess::ChannelPutRequester> const&, std::shared_ptr<epics::pvData::PVStructure> const&) (pdbsingle.cpp:230)
...