diff options
author | nkozlovskiy <nmk@ydb.tech> | 2023-10-11 19:11:46 +0300 |
---|---|---|
committer | nkozlovskiy <nmk@ydb.tech> | 2023-10-11 19:33:28 +0300 |
commit | 61b3971447e473726d6cdb23fc298e457b4d973c (patch) | |
tree | e2a2a864bb7717f7ae6138f6a3194a254dd2c7bb /contrib/libs/clang14-rt/lib/sanitizer_common/sanitizer_termination.cpp | |
parent | a674dc57d88d43c2e8e90a6084d5d2c988e0402c (diff) | |
download | ydb-61b3971447e473726d6cdb23fc298e457b4d973c.tar.gz |
add sanitizers dependencies
Diffstat (limited to 'contrib/libs/clang14-rt/lib/sanitizer_common/sanitizer_termination.cpp')
-rw-r--r-- | contrib/libs/clang14-rt/lib/sanitizer_common/sanitizer_termination.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/contrib/libs/clang14-rt/lib/sanitizer_common/sanitizer_termination.cpp b/contrib/libs/clang14-rt/lib/sanitizer_common/sanitizer_termination.cpp new file mode 100644 index 0000000000..6a54734353 --- /dev/null +++ b/contrib/libs/clang14-rt/lib/sanitizer_common/sanitizer_termination.cpp @@ -0,0 +1,99 @@ +//===-- sanitizer_termination.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 contains the Sanitizer termination functions CheckFailed and Die, +/// and the callback functionalities associated with them. +/// +//===----------------------------------------------------------------------===// + +#include "sanitizer_common.h" +#include "sanitizer_libc.h" + +namespace __sanitizer { + +static const int kMaxNumOfInternalDieCallbacks = 5; +static DieCallbackType InternalDieCallbacks[kMaxNumOfInternalDieCallbacks]; + +bool AddDieCallback(DieCallbackType callback) { + for (int i = 0; i < kMaxNumOfInternalDieCallbacks; i++) { + if (InternalDieCallbacks[i] == nullptr) { + InternalDieCallbacks[i] = callback; + return true; + } + } + return false; +} + +bool RemoveDieCallback(DieCallbackType callback) { + for (int i = 0; i < kMaxNumOfInternalDieCallbacks; i++) { + if (InternalDieCallbacks[i] == callback) { + internal_memmove(&InternalDieCallbacks[i], &InternalDieCallbacks[i + 1], + sizeof(InternalDieCallbacks[0]) * + (kMaxNumOfInternalDieCallbacks - i - 1)); + InternalDieCallbacks[kMaxNumOfInternalDieCallbacks - 1] = nullptr; + return true; + } + } + return false; +} + +static DieCallbackType UserDieCallback; +void SetUserDieCallback(DieCallbackType callback) { + UserDieCallback = callback; +} + +void NORETURN Die() { + if (UserDieCallback) + UserDieCallback(); + for (int i = kMaxNumOfInternalDieCallbacks - 1; i >= 0; i--) { + if (InternalDieCallbacks[i]) + InternalDieCallbacks[i](); + } + if (common_flags()->abort_on_error) + Abort(); + internal__exit(common_flags()->exitcode); +} + +static void (*CheckUnwindCallback)(); +void SetCheckUnwindCallback(void (*callback)()) { + CheckUnwindCallback = callback; +} + +void NORETURN CheckFailed(const char *file, int line, const char *cond, + u64 v1, u64 v2) { + u32 tid = GetTid(); + Printf("%s: CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx) (tid=%u)\n", + SanitizerToolName, StripModuleName(file), line, cond, (uptr)v1, + (uptr)v2, tid); + static atomic_uint32_t first_tid; + u32 cmp = 0; + if (!atomic_compare_exchange_strong(&first_tid, &cmp, tid, + memory_order_relaxed)) { + if (cmp == tid) { + // Recursing into CheckFailed. + } else { + // Another thread fails already, let it print the stack and terminate. + SleepForSeconds(2); + } + Trap(); + } + if (CheckUnwindCallback) + CheckUnwindCallback(); + Die(); +} + +} // namespace __sanitizer + +using namespace __sanitizer; + +extern "C" { +SANITIZER_INTERFACE_ATTRIBUTE +void __sanitizer_set_death_callback(void (*callback)(void)) { + SetUserDieCallback(callback); +} +} // extern "C" |