[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:
@@ -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;
|
||||
|
||||
|
||||
40
openmp/runtime/test/ompt/misc/lock_double_destroy.cpp
Normal file
40
openmp/runtime/test/ompt/misc/lock_double_destroy.cpp
Normal 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
|
||||
Reference in New Issue
Block a user