gcc/libsanitizer/sanitizer_common/sanitizer_thread_arg_retval.cpp
Jakub Jelinek 28219f7f99 libsanitizer: merge from upstream (c425db2eb558c263)
The following patch is result of libsanitizer/merge.sh
from c425db2eb558c263 (yesterday evening).

Bootstrapped/regtested on x86_64-linux and i686-linux (together with
the follow-up 3 patches I'm about to post).

BTW, seems upstream has added riscv64 support for I think lsan/tsan,
so if anyone is willing to try it there, it would be a matter of
copying e.g. the s390*-*-linux* libsanitizer/configure.tgt entry
to riscv64-*-linux* with the obvious s/s390x/riscv64/ change in it.
2023-11-15 12:45:58 +01:00

94 lines
2.4 KiB
C++

//===-- sanitizer_thread_arg_retval.cpp -------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is shared between sanitizer tools.
//
// Tracks thread arguments and return value for leak checking.
//===----------------------------------------------------------------------===//
#include "sanitizer_thread_arg_retval.h"
#include "sanitizer_placement_new.h"
namespace __sanitizer {
void ThreadArgRetval::CreateLocked(uptr thread, bool detached,
const Args& args) {
CheckLocked();
Data& t = data_[thread];
t = {};
t.gen = gen_++;
t.detached = detached;
t.args = args;
}
ThreadArgRetval::Args ThreadArgRetval::GetArgs(uptr thread) const {
__sanitizer::Lock lock(&mtx_);
auto t = data_.find(thread);
CHECK(t);
if (t->second.done)
return {};
return t->second.args;
}
void ThreadArgRetval::Finish(uptr thread, void* retval) {
__sanitizer::Lock lock(&mtx_);
auto t = data_.find(thread);
if (!t)
return;
if (t->second.detached) {
// Retval of detached thread connot be retrieved.
data_.erase(t);
return;
}
t->second.done = true;
t->second.args.arg_retval = retval;
}
u32 ThreadArgRetval::BeforeJoin(uptr thread) const {
__sanitizer::Lock lock(&mtx_);
auto t = data_.find(thread);
CHECK(t);
CHECK(!t->second.detached);
return t->second.gen;
}
void ThreadArgRetval::AfterJoin(uptr thread, u32 gen) {
__sanitizer::Lock lock(&mtx_);
auto t = data_.find(thread);
if (!t || gen != t->second.gen) {
// Thread was reused and erased by any other event.
return;
}
CHECK(!t->second.detached);
data_.erase(t);
}
void ThreadArgRetval::DetachLocked(uptr thread) {
CheckLocked();
auto t = data_.find(thread);
CHECK(t);
CHECK(!t->second.detached);
if (t->second.done) {
// We can't retrive retval after detached thread finished.
data_.erase(t);
return;
}
t->second.detached = true;
}
void ThreadArgRetval::GetAllPtrsLocked(InternalMmapVector<uptr>* ptrs) {
CheckLocked();
CHECK(ptrs);
data_.forEach([&](DenseMap<uptr, Data>::value_type& kv) -> bool {
ptrs->push_back((uptr)kv.second.args.arg_retval);
return true;
});
}
} // namespace __sanitizer