llvm-project

Форк
0
/
sanitizer_thread_arg_retval.cpp 
109 строк · 2.9 Кб
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-exception
6
//
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

18
namespace __sanitizer {
19

20
void 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

33
ThreadArgRetval::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

42
void 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

56
u32 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

75
void 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 invalid
80
    // join.
81
    return;
82
  }
83
  CHECK(!t->second.detached);
84
  data_.erase(t);
85
}
86

87
void 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

100
void 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 __sanitizer
110

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.