1 //===-- sanitizer_termination.cc --------------------------------*- C++ -*-===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 /// This file contains the Sanitizer termination functions CheckFailed and Die,
9 /// and the callback functionalities associated with them.
11 //===----------------------------------------------------------------------===//
13 #include "sanitizer_common.h"
14 #include "sanitizer_libc.h"
16 namespace __sanitizer
{
18 static const int kMaxNumOfInternalDieCallbacks
= 5;
19 static DieCallbackType InternalDieCallbacks
[kMaxNumOfInternalDieCallbacks
];
21 bool AddDieCallback(DieCallbackType callback
) {
22 for (int i
= 0; i
< kMaxNumOfInternalDieCallbacks
; i
++) {
23 if (InternalDieCallbacks
[i
] == nullptr) {
24 InternalDieCallbacks
[i
] = callback
;
31 bool RemoveDieCallback(DieCallbackType callback
) {
32 for (int i
= 0; i
< kMaxNumOfInternalDieCallbacks
; i
++) {
33 if (InternalDieCallbacks
[i
] == callback
) {
34 internal_memmove(&InternalDieCallbacks
[i
], &InternalDieCallbacks
[i
+ 1],
35 sizeof(InternalDieCallbacks
[0]) *
36 (kMaxNumOfInternalDieCallbacks
- i
- 1));
37 InternalDieCallbacks
[kMaxNumOfInternalDieCallbacks
- 1] = nullptr;
44 static DieCallbackType UserDieCallback
;
45 void SetUserDieCallback(DieCallbackType callback
) {
46 UserDieCallback
= callback
;
52 for (int i
= kMaxNumOfInternalDieCallbacks
- 1; i
>= 0; i
--) {
53 if (InternalDieCallbacks
[i
])
54 InternalDieCallbacks
[i
]();
56 if (common_flags()->abort_on_error
)
58 internal__exit(common_flags()->exitcode
);
61 static CheckFailedCallbackType CheckFailedCallback
;
62 void SetCheckFailedCallback(CheckFailedCallbackType callback
) {
63 CheckFailedCallback
= callback
;
66 const int kSecondsToSleepWhenRecursiveCheckFailed
= 2;
68 void NORETURN
CheckFailed(const char *file
, int line
, const char *cond
,
70 static atomic_uint32_t num_calls
;
71 if (atomic_fetch_add(&num_calls
, 1, memory_order_relaxed
) > 10) {
72 SleepForSeconds(kSecondsToSleepWhenRecursiveCheckFailed
);
76 if (CheckFailedCallback
) {
77 CheckFailedCallback(file
, line
, cond
, v1
, v2
);
79 Report("Sanitizer CHECK failed: %s:%d %s (%lld, %lld)\n", file
, line
, cond
,
84 } // namespace __sanitizer