11#include " sanitizer_common/sanitizer_atomic.h"
22
3+ #include < stdio.h>
34#include < stdlib.h>
45#include < stdint.h>
56#include < string.h>
@@ -20,8 +21,36 @@ static __sanitizer::atomic_uintptr_t caller_pcs[kMaxCallerPcs];
2021// that "too many errors" has already been reported.
2122static __sanitizer::atomic_uint32_t caller_pcs_sz;
2223
24+ #define MSG_PREFIX " ubsan: "
25+ #define MSG_SUFFIX " by 0x"
26+
27+ static char *append_str (const char *s, char *buf, const char *end) {
28+ for (const char *p = s; (buf < end) && (*p != ' \0 ' ); ++p, ++buf) *buf = *p;
29+ return buf;
30+ }
31+
32+ static char *append_hex (uintptr_t d, char *buf, const char *end) {
33+ // Print the address by nibbles.
34+ for (unsigned shift = sizeof (uintptr_t ) * 8 ; shift && buf < end;) {
35+ shift -= 4 ;
36+ unsigned nibble = (d >> shift) & 0xf ;
37+ *(buf++) = nibble < 10 ? nibble + ' 0' : nibble - 10 + ' a' ;
38+ }
39+ return buf;
40+ }
41+
42+ #if defined(__ANDROID__)
43+ extern " C" __attribute__((weak)) void android_set_abort_message (const char *);
44+ static void abort_with_message (const char *msg) {
45+ if (&android_set_abort_message) android_set_abort_message (msg);
46+ abort ();
47+ }
48+ #else
49+ static void abort_with_message (const char *) { abort (); }
50+ #endif
51+
2352SANITIZER_INTERFACE_WEAK_DEF (void , __ubsan_report_error, const char *msg,
24- uintptr_t caller, const char *decorated_msg ) {
53+ uintptr_t caller, int abort ) {
2554 if (caller == 0 )
2655 return ;
2756 while (true ) {
@@ -48,32 +77,21 @@ SANITIZER_INTERFACE_WEAK_DEF(void, __ubsan_report_error, const char *msg,
4877 return ;
4978 }
5079 __sanitizer::atomic_store_relaxed (&caller_pcs[sz], caller);
51- message (decorated_msg);
52- }
53- }
5480
55- __attribute__ ((noinline)) static void decorate_msg(char *buf,
56- uintptr_t caller) {
57- // print the address by nibbles
58- for (unsigned shift = sizeof (uintptr_t ) * 8 ; shift;) {
59- shift -= 4 ;
60- unsigned nibble = (caller >> shift) & 0xf ;
61- *(buf++) = nibble < 10 ? nibble + ' 0' : nibble - 10 + ' a' ;
62- }
63- // finish the message
64- buf[0 ] = ' \n ' ;
65- buf[1 ] = ' \0 ' ;
66- }
81+ char msg_buf[128 ] = MSG_PREFIX;
82+ const char *end = msg_buf + sizeof (msg_buf);
83+ char *p = append_str (msg, msg_buf + sizeof (MSG_PREFIX) - 1 , end);
84+ p = append_str (MSG_SUFFIX, p, end);
85+ p = append_hex (caller, p, end);
86+ if (p < end) *p++ = ' \n ' ;
6787
68- #if defined(__ANDROID__)
69- extern " C" __attribute__((weak)) void android_set_abort_message (const char *);
70- static void abort_with_message (const char *msg) {
71- if (&android_set_abort_message) android_set_abort_message (msg);
72- abort ();
88+ // Zero terminate.
89+ if (p == end) --p;
90+ *p = ' \0 ' ;
91+ message (msg_buf);
92+ if (abort) abort_with_message (msg_buf); \
93+ }
7394}
74- #else
75- static void abort_with_message (const char *) { abort (); }
76- #endif
7795
7896#if SANITIZER_DEBUG
7997namespace __sanitizer {
@@ -90,28 +108,16 @@ void NORETURN CheckFailed(const char *file, int, const char *cond, u64, u64) {
90108
91109#define INTERFACE extern " C" __attribute__((visibility(" default" )))
92110
93- // How many chars we need to reserve to print an address.
94- constexpr unsigned kAddrBuf = SANITIZER_WORDSIZE / 4 ;
95- #define MSG_TMPL (msg ) " ubsan: " msg " by 0x"
96- #define MSG_TMPL_END (buf, msg ) (buf + sizeof (MSG_TMPL(msg)) - 1 )
97- // Reserve an additional byte for '\n'.
98- #define MSG_BUF_LEN (msg ) (sizeof (MSG_TMPL(msg)) + kAddrBuf + 1 )
99-
100111#define HANDLER_RECOVER (name, msg ) \
101112 INTERFACE void __ubsan_handle_##name##_minimal() { \
102113 uintptr_t caller = GET_CALLER_PC (); \
103- char msg_buf[MSG_BUF_LEN (msg)] = MSG_TMPL (msg); \
104- decorate_msg (MSG_TMPL_END (msg_buf, msg), caller); \
105- __ubsan_report_error (msg, caller, msg_buf); \
114+ __ubsan_report_error (msg, caller, 0 ); \
106115 }
107116
108117#define HANDLER_NORECOVER (name, msg ) \
109118 INTERFACE void __ubsan_handle_##name##_minimal_abort() { \
110119 uintptr_t caller = GET_CALLER_PC (); \
111- char msg_buf[MSG_BUF_LEN (msg)] = MSG_TMPL (msg); \
112- decorate_msg (MSG_TMPL_END (msg_buf, msg), caller); \
113- __ubsan_report_error (msg, caller, msg_buf); \
114- abort_with_message (msg_buf); \
120+ __ubsan_report_error (msg, caller, 1 ); \
115121 }
116122
117123#define HANDLER (name, msg ) \
0 commit comments