Hello!

In SyncEvolution, I am allowing the usage of a background thread for the
initialization of a datastore. One of the nightly tests ran into a crash
related to that. The TestHTTP.testAbortThread test aborts a sync before
or while it still starts up. It looks like, depending on timing (failure
is rare - I don't remember seeing it before), the background thread
still runs while the engine shuts down. The exact call stack when that
goes bad is this:

==17106== Invalid write of size 2
==17106==    at 0x486A1EB: sysync::TScriptContext::ExecuteScript(std::string 
const&, sysync::TItemField**, bool, sysync::TFuncTable const*, void*, 
sysync::TMultiFieldItem*, bool, sysync::TMultiFieldItem*, bool, bool) 
(scriptcontext.cpp:4405)
==17106==    by 0x486DDDC: sysync::TScriptContext::executeTest(bool, 
sysync::TScriptContext*, std::string const&, sysync::TFuncTable const*, void*, 
sysync::TMultiFieldItem*, bool, sysync::TMultiFieldItem*, bool) 
(scriptcontext.cpp:3545)
==17106==    by 0x47D8206: sysync::TPluginApiDS::apiReadSyncSet(bool) 
(pluginapids.cpp:1047)
==17106==    by 0x4810798: sysync::TCustomImplDS::implStartDataRead() 
(customimplds.cpp:1708)
==17106==    by 0x4878A41: sysync::TStdLogicDS::performStartSync() 
(stdlogicds.cpp:313)
==17106==    by 0x4879434: sysync::StartSyncThreadFunc(sysync::TThreadObject*, 
unsigned long) (stdlogicds.cpp:464)
==17106==    by 0x47F636D: sysync::TThreadObject::execute() 
(platform_thread.cpp:254)
==17106==    by 0x47F68B7: PosixThreadFunc (platform_thread.cpp:51)
==17106==    by 0x44E9CF0: start_thread (pthread_create.c:311)
==17106==    by 0x46F3C3D: clone (clone.S:131)
==17106==  Address 0xaa54860 is 72 bytes inside a block of size 584 free'd
==17106==    at 0x402A0E8: operator delete(void*) (in 
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==17106==    by 0x4868C53: sysync::TScriptContext::~TScriptContext() 
(scriptcontext.cpp:2394)
==17106==    by 0x4813046: sysync::TCustomImplDS::InternalResetDataStore() 
(customimplds.cpp:1006)
==17106==    by 0x47DBE11: sysync::TPluginApiDS::dsResetDataStore() 
(customimplds.h:399)
==17106==    by 0x483DB64: sysync::TLocalEngineDS::engResetDataStore() 
(localengineds.cpp:1370)
==17106==    by 0x482DF41: 
sysync::TLocalEngineDS::engTerminateDatastore(unsigned short) 
(localengineds.cpp:4520)
==17106==    by 0x47D3481: sysync::TPluginApiDS::announceAgentDestruction() 
(pluginapids.cpp:312)
==17106==    by 0x48A1682: sysync::TSyncSession::announceDestruction() 
(syncsession.cpp:1334)
==17106==    by 0x47D046A: sysync::TPluginApiAgent::TerminateSession() 
(pluginapiagent.cpp:338)
==17106==    by 0x47F14DD: 
sysync::TServerEngineInterface::CloseSession(sysync::SessionType*) 
(enginesessiondispatch.cpp:434)
==17106==    by 0x48229AA: sysync::CloseSession(void*, sysync::SessionType*) 
(engineentry.cpp:113)
==17106==    by 0x42E4379: 
sysync::TEngineModuleBridge::CloseSession(sysync::SessionType*) 
(enginemodulebridge.cpp:149)
==17106==    by 0x417FE8A: 
boost::detail::sp_counted_impl_pd<sysync::SessionType*, 
SyncEvo::FreeEngineItem>::dispose() (SynthesisEngine.cpp:64)
==17106==    by 0x807DCB7: boost::detail::shared_count::~shared_count() 
(sp_counted_base_gcc_x86.hpp:145)
==17106==    by 0x4269036: SyncEvo::SyncContext::doSync() (shared_ptr.hpp:169)
==17106==    by 0x426FCFC: SyncEvo::SyncContext::sync(SyncEvo::SyncReport*) 
(SyncContext.cpp:3422)
==17106==    by 0x8083B17: 
SyncEvo::SessionHelper::doSync(SyncEvo::SessionCommon::SyncParams const&, 
boost::shared_ptr<GDBusCXX::Result2<bool, SyncEvo::SyncReport> > const&) 
(session-helper.cpp:222)
==17106==    by 0x808B55E: 
boost::detail::function::function_obj_invoker0<boost::_bi::bind_t<bool, 
boost::_mfi::mf2<bool, SyncEvo::SessionHelper, 
SyncEvo::SessionCommon::SyncParams const&, 
boost::shared_ptr<GDBusCXX::Result2<bool, SyncEvo::SyncReport> > const&>, 
boost::_bi::list3<boost::_bi::value<SyncEvo::SessionHelper*>, 
boost::_bi::value<SyncEvo::SessionCommon::SyncParams>, 
boost::_bi::value<boost::shared_ptr<GDBusCXX::Result2<bool, 
SyncEvo::SyncReport> > > > >, 
bool>::invoke(boost::detail::function::function_buffer&) 
(mem_fn_template.hpp:274)
==17106==    by 0x8083664: SyncEvo::SessionHelper::run() 
(function_template.hpp:1013)
==17106==    by 0x807C7D7: main (sync-helper.cpp:187)

In other words, the background thread is still using the script context
that the main thread has already destroyed.

Somewhere in the main thread's call chain there needs to be a "tell
helper thread to abort (optional) and wait for it (required)". I am not
sure where to put that. Any suggestion?

doSync() should have called SessionStep(sysync::STEPCMD_ABORT) and
waited for sysync::STEPCMD_DONE or sysync::STEPCMD_ERROR, so the engine
should have had a chance to wait for the background thread before the
CloseSession() call.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



_______________________________________________
os-libsynthesis mailing list
[email protected]
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis

Reply via email to