Browse Source

Fix read-after-free on task termination of handle partition switch codelet

We need to get the callback pointer for the codelet before
notifying dependencies, in case dependencies free the codelet (see
starpu_data_unregister for instance)
Samuel Thibault 4 years ago
parent
commit
4ca244c536
1 changed files with 10 additions and 5 deletions
  1. 10 5
      src/core/jobs.c

+ 10 - 5
src/core/jobs.c

@@ -405,6 +405,13 @@ void _starpu_handle_job_termination(struct _starpu_job *j)
 			_starpu_spin_unlock(&handle->header_lock);
 	}
 
+	/* Get callback pointer for codelet before notifying dependencies, in
+	   case dependencies free the codelet (see starpu_data_unregister for
+	   instance) */
+	void (*callback)(void *) = task->callback_func;
+	if (!callback && task->cl)
+		callback = task->cl->callback_func;
+
 	_STARPU_TRACE_TASK_NAME(j);
 
 	/* If this is a continuation, we do not notify task/tag dependencies
@@ -425,7 +432,7 @@ void _starpu_handle_job_termination(struct _starpu_job *j)
 	{
 		/* the callback is executed after the dependencies so that we may remove the tag
 		 * of the task itself */
-		if (task->callback_func || (task->cl && task->cl->callback_func))
+		if (callback)
 		{
 			int profiling = starpu_profiling_status_get();
 			if (profiling && task->profiling_info)
@@ -443,10 +450,8 @@ void _starpu_handle_job_termination(struct _starpu_job *j)
 			_starpu_set_current_task(task);
 
 			_STARPU_TRACE_START_CALLBACK(j);
-			if (task->callback_func)
-				task->callback_func(task->callback_arg);
-			else
-				task->cl->callback_func(task->callback_arg);
+			if (callback)
+				callback(task->callback_arg);
 			_STARPU_TRACE_END_CALLBACK(j);
 
 			_starpu_set_current_task(current_task);