brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · 754fd7b Raw
110 lines · cpp
1//===-- sanitizer_thread_arg_retval.cpp -------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is shared between sanitizer tools.10//11// Tracks thread arguments and return value for leak checking.12//===----------------------------------------------------------------------===//13 14#include "sanitizer_thread_arg_retval.h"15 16#include "sanitizer_placement_new.h"17 18namespace __sanitizer {19 20void ThreadArgRetval::CreateLocked(uptr thread, bool detached,21                                   const Args& args) {22  CheckLocked();23  Data& t = data_[thread];24  t = {};25  t.gen = gen_++;26  static_assert(sizeof(gen_) == sizeof(u32) && kInvalidGen == UINT32_MAX);27  if (gen_ == kInvalidGen)28    gen_ = 0;29  t.detached = detached;30  t.args = args;31}32 33ThreadArgRetval::Args ThreadArgRetval::GetArgs(uptr thread) const {34  __sanitizer::Lock lock(&mtx_);35  auto t = data_.find(thread);36  CHECK(t);37  if (t->second.done)38    return {};39  return t->second.args;40}41 42void ThreadArgRetval::Finish(uptr thread, void* retval) {43  __sanitizer::Lock lock(&mtx_);44  auto t = data_.find(thread);45  if (!t)46    return;47  if (t->second.detached) {48    // Retval of detached thread connot be retrieved.49    data_.erase(t);50    return;51  }52  t->second.done = true;53  t->second.args.arg_retval = retval;54}55 56u32 ThreadArgRetval::BeforeJoin(uptr thread) const {57  __sanitizer::Lock lock(&mtx_);58  auto t = data_.find(thread);59  if (t && !t->second.detached) {60    return t->second.gen;61  }62  if (!common_flags()->detect_invalid_join)63    return kInvalidGen;64  const char* reason = "unknown";65  if (!t) {66    reason = "already joined";67  } else if (t->second.detached) {68    reason = "detached";69  }70  Report("ERROR: %s: Joining %s thread, aborting.\n", SanitizerToolName,71         reason);72  Die();73}74 75void ThreadArgRetval::AfterJoin(uptr thread, u32 gen) {76  __sanitizer::Lock lock(&mtx_);77  auto t = data_.find(thread);78  if (!t || gen != t->second.gen) {79    // Thread was reused and erased by any other event, or we had an invalid80    // join.81    return;82  }83  CHECK(!t->second.detached);84  data_.erase(t);85}86 87void ThreadArgRetval::DetachLocked(uptr thread) {88  CheckLocked();89  auto t = data_.find(thread);90  CHECK(t);91  CHECK(!t->second.detached);92  if (t->second.done) {93    // We can't retrive retval after detached thread finished.94    data_.erase(t);95    return;96  }97  t->second.detached = true;98}99 100void ThreadArgRetval::GetAllPtrsLocked(InternalMmapVector<uptr>* ptrs) {101  CheckLocked();102  CHECK(ptrs);103  data_.forEach([&](DenseMap<uptr, Data>::value_type& kv) -> bool {104    ptrs->push_back((uptr)kv.second.args.arg_retval);105    return true;106  });107}108 109}  // namespace __sanitizer110