}
}
+__attribute__((noinline)) static void decorate_msg(char *buf,
+ uintptr_t caller) {
+ // print the address by nibbles
+ for (unsigned shift = sizeof(uintptr_t) * 8; shift;) {
+ shift -= 4;
+ unsigned nibble = (caller >> shift) & 0xf;
+ *(buf++) = nibble < 10 ? nibble + '0' : nibble - 10 + 'a';
+ }
+ // finish the message
+ buf[0] = '\n';
+ buf[1] = '\0';
+}
+
#if defined(__ANDROID__)
extern "C" __attribute__((weak)) void android_set_abort_message(const char *);
static void abort_with_message(const char *msg) {
#define INTERFACE extern "C" __attribute__((visibility("default")))
-// FIXME: add caller pc to the error message (possibly as "ubsan: error-type
-// @1234ABCD").
+// How many chars we need to reserve to print an address.
+constexpr unsigned kAddrBuf = SANITIZER_WORDSIZE / 4;
+#define MSG_TMPL(msg) "ubsan: " msg " by 0x"
+#define MSG_TMPL_END(buf, msg) (buf + sizeof(MSG_TMPL(msg)) - 1)
+// Reserve an additional byte for '\n'.
+#define MSG_BUF_LEN(msg) (sizeof(MSG_TMPL(msg)) + kAddrBuf + 1)
+
#define HANDLER_RECOVER(name, msg) \
INTERFACE void __ubsan_handle_##name##_minimal() { \
- if (!report_this_error(GET_CALLER_PC())) return; \
- message("ubsan: " msg "\n"); \
+ uintptr_t caller = GET_CALLER_PC(); \
+ if (!report_this_error(caller)) return; \
+ char msg_buf[MSG_BUF_LEN(msg)] = MSG_TMPL(msg); \
+ decorate_msg(MSG_TMPL_END(msg_buf, msg), caller); \
+ message(msg_buf); \
}
#define HANDLER_NORECOVER(name, msg) \
INTERFACE void __ubsan_handle_##name##_minimal_abort() { \
- message("ubsan: " msg "\n"); \
- abort_with_message("ubsan: " msg); \
+ char msg_buf[MSG_BUF_LEN(msg)] = MSG_TMPL(msg); \
+ decorate_msg(MSG_TMPL_END(msg_buf, msg), GET_CALLER_PC()); \
+ message(msg_buf); \
+ abort_with_message(msg_buf); \
}
#define HANDLER(name, msg) \
#include <stdio.h>
int *_Nonnull h() {
- // CHECK: nullability-return
+ // CHECK: nullability-return by 0x{{[[:xdigit:]]+$}}
return NULL;
}
__attribute__((returns_nonnull))
int *i() {
- // CHECK: nonnull-return
+ // CHECK: nonnull-return by 0x{{[[:xdigit:]]+$}}
return NULL;
}
__attribute__((noinline))
int f(int x, int y) {
- // CHECK: mul-overflow
+ // CHECK: mul-overflow by 0x{{[[:xdigit:]]+$}}
return x * y;
}
__attribute__((noinline))
int g(int x, int y) {
- // CHECK: mul-overflow
+ // CHECK: mul-overflow by 0x{{[[:xdigit:]]+$}}
return x * (y + 1);
}