Skip to content

Commit 511cfaf

Browse files
committed
[OpenMP] avoid segv for a lock that has already been destroyed
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.
1 parent 357297c commit 511cfaf

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

openmp/runtime/src/kmp_lock.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3242,6 +3242,8 @@ static void __kmp_destroy_indirect_lock(kmp_dyna_lock_t *lock) {
32423242
kmp_uint32 gtid = __kmp_entry_gtid();
32433243
kmp_indirect_lock_t *l =
32443244
__kmp_lookup_indirect_lock((void **)lock, "omp_destroy_lock");
3245+
if (l == nullptr)
3246+
return; // avoid segv if lock already destroyed
32453247
KMP_I_LOCK_FUNC(l, destroy)(l->lock);
32463248
kmp_indirect_locktag_t tag = l->type;
32473249

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: %libomp-cxx-compile-and-run | FileCheck %s
2+
// REQUIRES: ompt
3+
#include "callback.h"
4+
#include "omp_testsuite.h"
5+
6+
// tests that the destructor doesn't segv even though
7+
// ompt_finalize_tool() destroys the lock
8+
struct myLock {
9+
omp_lock_t lock;
10+
myLock() { omp_init_lock(&lock); }
11+
~myLock() { omp_destroy_lock(&lock); }
12+
};
13+
14+
myLock lock;
15+
16+
int main() {
17+
go_parallel_nthreads(2);
18+
19+
printf("Before ompt_finalize_tool\n");
20+
ompt_finalize_tool();
21+
printf("After ompt_finalize_tool\n");
22+
23+
return get_exit_value();
24+
}
25+
26+
// CHECK: 0: NULL_POINTER=[[NULL:.*$]]
27+
// CHECK: {{^}}[[THREAD_ID:[0-9]+]]: ompt_event_thread_begin:
28+
// CHECK-SAME: thread_type=ompt_thread_initial=1
29+
30+
// CHECK: {{^}}[[THREAD_ID]]: ompt_event_init_lock
31+
32+
// CHECK: {{^}}[[THREAD_ID]]: ompt_event_parallel_begin
33+
// CHECK: {{^}}[[THREAD_ID]]: ompt_event_parallel_end
34+
35+
// CHECK: {{^}}Before ompt_finalize_tool
36+
37+
// CHECK: {{^}}[[THREAD_ID]]: ompt_event_thread_end: thread_id=[[THREAD_ID]]
38+
// CHECK: 0: ompt_event_runtime_shutdown
39+
40+
// CHECK: {{^}}After ompt_finalize_tool

0 commit comments

Comments
 (0)