diff options
author | Andrii Kalinich <AKalinich@luxoft.com> | 2019-09-26 14:41:19 -0400 |
---|---|---|
committer | Andrii Kalinich <AKalinich@luxoft.com> | 2019-09-27 11:35:31 -0400 |
commit | 46e8b4a9badea2e5bd4e9d06bdbb3be089e26e77 (patch) | |
tree | 608d9aaf92599bdf26ff01330a212a5613805d18 | |
parent | 35e6a7ec5bbcb27bd972a2db07a18c2294b1bc0c (diff) | |
download | sdl_core-46e8b4a9badea2e5bd4e9d06bdbb3be089e26e77.tar.gz |
Fix SDL crash on app service unpublishingfix/fix_random_sdl_crash
There was found an unsafe work with STL map
in AppServiceManager - during service unpublishing
there might be a possibility when component
iterates over published_services_ and another
function indirectly erases the same element from
the same map what may cause an undefined behavior
during iteration over the map.
To make this safer - iteration over the map and
erasure of element in the map were splitted onto
two separate atomic actions.
-rw-r--r-- | src/components/application_manager/src/app_service_manager.cc | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/src/components/application_manager/src/app_service_manager.cc b/src/components/application_manager/src/app_service_manager.cc index a85921a8cd..afcc7ae1dd 100644 --- a/src/components/application_manager/src/app_service_manager.cc +++ b/src/components/application_manager/src/app_service_manager.cc @@ -223,13 +223,21 @@ bool AppServiceManager::UnpublishAppService(const std::string service_id) { void AppServiceManager::UnpublishServices(const uint32_t connection_key) { LOG4CXX_AUTO_TRACE(logger_); LOG4CXX_DEBUG(logger_, "Unpublishing all app services: " << connection_key); - sync_primitives::AutoLock lock(published_services_lock_); - for (auto it = published_services_.begin(); it != published_services_.end(); - ++it) { - if (it->second.connection_key == connection_key) { - UnpublishAppService(it->first); + + std::list<std::string> app_published_services; + { + sync_primitives::AutoLock lock(published_services_lock_); + for (auto it = published_services_.begin(); it != published_services_.end(); + ++it) { + if (it->second.connection_key == connection_key) { + app_published_services.push_back(it->first); + } } } + + for (auto& service_id : app_published_services) { + UnpublishAppService(service_id); + } } void AppServiceManager::OnAppActivated(ApplicationConstSharedPtr app) { |