[OpenMP] avoid segv for a lock that has already been destroyed (#145625)

This can happen in static destructors when called after the
  runtime is already shutdown (e.g., by ompt_finalize_tool). Even
  though it is technically an error to call omp_destroy_lock after
shutdown, the application doesn't necessarily know that omp_destroy_lock
  was already called. This is safe becaues all indirect locks are
  destoryed in __kmp_cleanup_indirect_user_locks so the return
  value will always be valid or a nullptr, not garbage.
This commit is contained in:
Larry Meadows
2025-06-25 12:08:45 -07:00
committed by GitHub
parent 7aeb1a1fd8
commit aec88679db
2 changed files with 42 additions and 0 deletions

View File

@@ -3242,6 +3242,8 @@ static void __kmp_destroy_indirect_lock(kmp_dyna_lock_t *lock) {
kmp_uint32 gtid = __kmp_entry_gtid();
kmp_indirect_lock_t *l =
__kmp_lookup_indirect_lock((void **)lock, "omp_destroy_lock");
if (l == nullptr)
return; // avoid segv if lock already destroyed
KMP_I_LOCK_FUNC(l, destroy)(l->lock);
kmp_indirect_locktag_t tag = l->type;

View File

@@ -0,0 +1,40 @@
// RUN: %libomp-cxx-compile-and-run | FileCheck %s
// REQUIRES: ompt
#include "callback.h"
#include "omp_testsuite.h"
// tests that the destructor doesn't segv even though
// ompt_finalize_tool() destroys the lock
struct myLock {
omp_lock_t lock;
myLock() { omp_init_lock(&lock); }
~myLock() { omp_destroy_lock(&lock); }
};
myLock lock;
int main() {
go_parallel_nthreads(2);
printf("Before ompt_finalize_tool\n");
ompt_finalize_tool();
printf("After ompt_finalize_tool\n");
return get_exit_value();
}
// CHECK: 0: NULL_POINTER=[[NULL:.*$]]
// CHECK: {{^}}[[THREAD_ID:[0-9]+]]: ompt_event_thread_begin:
// CHECK-SAME: thread_type=ompt_thread_initial=1
// CHECK: {{^}}[[THREAD_ID]]: ompt_event_init_lock
// CHECK: {{^}}[[THREAD_ID]]: ompt_event_parallel_begin
// CHECK: {{^}}[[THREAD_ID]]: ompt_event_parallel_end
// CHECK: {{^}}Before ompt_finalize_tool
// CHECK: {{^}}[[THREAD_ID]]: ompt_event_thread_end: thread_id=[[THREAD_ID]]
// CHECK: 0: ompt_event_runtime_shutdown
// CHECK: {{^}}After ompt_finalize_tool