From: Arnaud Giersch Date: Tue, 2 May 2023 14:12:18 +0000 (+0200) Subject: Fix use-after-free observed with the s4u-operation examples. X-Git-Tag: v3.34~139 X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/2e41f2d990dc6014f0b8961fba09a6ecef7f5894 Fix use-after-free observed with the s4u-operation examples. --- diff --git a/include/simgrid/s4u/Activity.hpp b/include/simgrid/s4u/Activity.hpp index bc027130b5..82a880a2c1 100644 --- a/include/simgrid/s4u/Activity.hpp +++ b/include/simgrid/s4u/Activity.hpp @@ -138,6 +138,9 @@ public: void complete(Activity::State state) { + // Ensure that the current activity remains alive until the end of the function, even if its last reference is + // released by the on_completion() callbacks. + ActivityPtr keepalive(this); state_ = state; on_completion(*this); if (state == State::FINISHED) diff --git a/src/kernel/EngineImpl.cpp b/src/kernel/EngineImpl.cpp index e3e701a47e..f4a3d747db 100644 --- a/src/kernel/EngineImpl.cpp +++ b/src/kernel/EngineImpl.cpp @@ -356,24 +356,27 @@ void EngineImpl::handle_ended_actions() const while (auto* action = model->extract_failed_action()) { XBT_DEBUG(" Handling Action %p", action); if (action->get_activity() != nullptr) { // Skip vcpu actions + activity::ActivityImplPtr activity(action->get_activity()); // Action failures are not automatically reported when the action is started by maestro (as in SimDAG) - if (action->get_activity()->get_actor() == maestro_) - action->get_activity()->get_iface()->complete(s4u::Activity::State::FAILED); + if (activity->get_actor() == maestro_) + activity->get_iface()->complete(s4u::Activity::State::FAILED); - activity::ActivityImplPtr(action->get_activity())->finish(); + activity->finish(); } } XBT_DEBUG("Handling the terminated actions (if any)"); while (auto* action = model->extract_done_action()) { XBT_DEBUG(" Handling Action %p", action); if (action->get_activity() != nullptr) { + activity::ActivityImplPtr activity(action->get_activity()); + // Action termination are not automatically reported when the action is started by maestro (as in SimDAG) - action->get_activity()->set_finish_time(action->get_finish_time()); + activity->set_finish_time(action->get_finish_time()); - if (action->get_activity()->get_actor() == maestro_) - action->get_activity()->get_iface()->complete(s4u::Activity::State::FINISHED); + if (activity->get_actor() == maestro_) + activity->get_iface()->complete(s4u::Activity::State::FINISHED); - activity::ActivityImplPtr(action->get_activity())->finish(); + activity->finish(); } } }