Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix use-after-free observed with the s4u-operation examples.
authorArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Tue, 2 May 2023 14:12:18 +0000 (16:12 +0200)
committerArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Tue, 2 May 2023 14:39:20 +0000 (16:39 +0200)
include/simgrid/s4u/Activity.hpp
src/kernel/EngineImpl.cpp

index bc02713..82a880a 100644 (file)
@@ -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)
index e3e701a..f4a3d74 100644 (file)
@@ -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();
       }
     }
   }