From e6fc009b281d02d29b098fc0b95202f5fc324b04 Mon Sep 17 00:00:00 2001 From: Larry Meadows Date: Fri, 7 Nov 2025 10:15:48 -0800 Subject: [PATCH] SWDEV-552584 fix racy null pointer exception for ompt_callback_task_schedule for ompt-task_early_fulfill tasks (#980) * Fix for SWDEV-552584 Two calls to ompt_callback_task_scheduled were issued for the same prior task. One of them was ompt_task_complete, which causes internal storage to be release and a pointer zeroed. The other was ompt_task_early_fulfill, which attempted to reference the pointer. The callbacks could come in any order as they were from different threads, thus causing a null pointer dereference on occasion. The code was changed to do nothing for the early_fulfill. Additional null pointer checks were added. * formatting * Update ompt.cpp Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Jonathan R. Madsen Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../source/lib/rocprofiler-sdk/ompt/ompt.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/ompt/ompt.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/ompt/ompt.cpp index f41ef20997..bdebd8e41f 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/ompt/ompt.cpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/ompt/ompt.cpp @@ -164,10 +164,18 @@ ompt_task_schedule_callback(ompt_data_t* prior_task_data, context::pop_latest_correlation_id(corr_id); corr_id->sub_ref_count(); + /* Warning: some tasks like early_fulfill may be scheduled + * out twice. The ordering between the early_fulfill and the complete + * (for example) is not specified. In this case the prior_task_state + * needs to be added to the early return if condition below. + */ auto* pprior = INTERNAL(prior_task_data); auto* pnext = INTERNAL(next_task_data); assert(pprior != nullptr); - auto* state_prior = reinterpret_cast(pprior->ptr); + auto* state_prior = reinterpret_cast(pprior->ptr); + if(state_prior == nullptr) + ROCP_FATAL << "state_prior == nullptr prior_task_status: " << prior_task_status << "."; + auto* state_next = pnext ? reinterpret_cast(pnext->ptr) : nullptr; auto* prior_corrid = context::get_latest_correlation_id(); if(state_prior->corr_id == prior_corrid && state_prior->task_flags != 0) @@ -182,9 +190,10 @@ ompt_task_schedule_callback(ompt_data_t* prior_task_data, context::push_correlation_id(state_next->corr_id); } if(prior_task_status == ompt_task_yield || prior_task_status == ompt_task_detach || - prior_task_status == ompt_task_switch) + prior_task_status == ompt_task_switch || prior_task_status == ompt_task_early_fulfill) return; // the prior task is done + assert(state_prior != nullptr); assert(state_prior->task_flags != 0); if(prior_task_status == ompt_task_complete) {