1
- #include < atomic>
1
+ #include " sanitizer_common/sanitizer_atomic.h"
2
+
2
3
#include < stdlib.h>
4
+ #include < stdint.h>
3
5
#include < string.h>
4
6
#include < unistd.h>
5
7
@@ -8,37 +10,38 @@ static void message(const char *msg) {
8
10
}
9
11
10
12
static const int kMaxCallerPcs = 20 ;
11
- static std::atomic< void *> caller_pcs[kMaxCallerPcs ];
13
+ static __sanitizer:: atomic_uintptr_t caller_pcs[kMaxCallerPcs ];
12
14
// Number of elements in caller_pcs. A special value of kMaxCallerPcs + 1 means
13
15
// that "too many errors" has already been reported.
14
- static std::atomic< int > caller_pcs_sz;
16
+ static __sanitizer:: atomic_uint32_t caller_pcs_sz;
15
17
16
- __attribute__ ((noinline))
17
- static bool report_this_error( void * caller) {
18
- if (caller == nullptr ) return false ;
18
+ __attribute__ ((noinline)) static bool report_this_error( void *caller_p) {
19
+ uintptr_t caller = reinterpret_cast < uintptr_t >(caller_p);
20
+ if (caller == 0 ) return false ;
19
21
while (true ) {
20
- int sz = caller_pcs_sz. load (std::memory_order_relaxed );
21
- if (sz > kMaxCallerPcs ) return false ; // early exit
22
+ unsigned sz = __sanitizer::atomic_load_relaxed (&caller_pcs_sz );
23
+ if (sz > kMaxCallerPcs ) return false ; // early exit
22
24
// when sz==kMaxCallerPcs print "too many errors", but only when cmpxchg
23
25
// succeeds in order to not print it multiple times.
24
26
if (sz > 0 && sz < kMaxCallerPcs ) {
25
- void * p;
26
- for (int i = 0 ; i < sz; ++i) {
27
- p = caller_pcs[i]. load (std::memory_order_relaxed );
28
- if (p == nullptr ) break ; // Concurrent update.
27
+ uintptr_t p;
28
+ for (unsigned i = 0 ; i < sz; ++i) {
29
+ p = __sanitizer::atomic_load_relaxed (& caller_pcs[i]);
30
+ if (p == 0 ) break ; // Concurrent update.
29
31
if (p == caller) return false ;
30
32
}
31
- if (p == nullptr ) continue ; // FIXME: yield?
33
+ if (p == 0 ) continue ; // FIXME: yield?
32
34
}
33
35
34
- if (!caller_pcs_sz.compare_exchange_strong (sz, sz + 1 ))
35
- continue ; // Concurrent update! Try again from the start.
36
+ if (!__sanitizer::atomic_compare_exchange_strong (
37
+ &caller_pcs_sz, &sz, sz + 1 , __sanitizer::memory_order_seq_cst))
38
+ continue ; // Concurrent update! Try again from the start.
36
39
37
40
if (sz == kMaxCallerPcs ) {
38
41
message (" ubsan: too many errors\n " );
39
42
return false ;
40
43
}
41
- caller_pcs[sz]. store (caller, std::memory_order_relaxed );
44
+ __sanitizer::atomic_store_relaxed (& caller_pcs[sz], caller );
42
45
return true ;
43
46
}
44
47
}
0 commit comments