[PATCH] D131914: [ubsan-minimal] Report the address of an error
Igor Kudrin via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 15 11:57:44 PDT 2022
ikudrin created this revision.
ikudrin added reviewers: eugenis, pcc, vitalybuka, vsk, filcab, delcypher.
ikudrin added a project: LLVM.
Herald added a subscriber: Enna1.
Herald added a project: All.
ikudrin requested review of this revision.
Herald added a project: Sanitizers.
Herald added a subscriber: Sanitizers.
This implements a FIXME in the runtime library and adds printing the address at the end of the message as "@123abc". The buffer for the message is allocated on the stack in a handler, so the stack memory consumption is slightly increased. No additional external dependencies are added.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D131914
Files:
compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
Index: compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
===================================================================
--- compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
+++ compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
@@ -20,9 +20,10 @@
// that "too many errors" has already been reported.
static __sanitizer::atomic_uint32_t caller_pcs_sz;
-__attribute__((noinline)) static bool report_this_error(void *caller_p) {
- uintptr_t caller = reinterpret_cast<uintptr_t>(caller_p);
- if (caller == 0) return false;
+__attribute__((noinline)) static bool
+report_this_error(__sanitizer::uptr caller) {
+ if (caller == 0)
+ return false;
while (true) {
unsigned sz = __sanitizer::atomic_load_relaxed(&caller_pcs_sz);
if (sz > kMaxCallerPcs) return false; // early exit
@@ -51,6 +52,29 @@
}
}
+__attribute__((noinline)) static void decorate_msg(char *buf,
+ __sanitizer::uptr caller) {
+ unsigned int shift = sizeof(__sanitizer::uptr) * 8 - 4;
+ __sanitizer::uptr mask = __sanitizer::uptr(0xf) << shift;
+ // skip leading zeroes
+ while (shift > 0 && !(caller & mask)) {
+ mask >>= 4;
+ shift -= 4;
+ }
+ // print remaining nibbles
+ for (;;) {
+ unsigned int nibble = (caller & mask) >> shift;
+ *(buf++) = nibble < 10 ? nibble + '0' : nibble - 10 + 'a';
+ if (!shift)
+ break;
+ mask >>= 4;
+ shift -= 4;
+ }
+ // 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) {
@@ -76,18 +100,28 @@
#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 any address.
+static const unsigned int kMaxAddrBuf = SANITIZER_WORDSIZE / 4;
+#define MSG_TMPL(msg) "ubsan: " msg " @"
+#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)) + kMaxAddrBuf + 1)
+
#define HANDLER_RECOVER(name, msg) \
INTERFACE void __ubsan_handle_##name##_minimal() { \
- if (!report_this_error(__builtin_return_address(0))) return; \
- message("ubsan: " msg "\n"); \
+ __sanitizer::uptr 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) \
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D131914.452760.patch
Type: text/x-patch
Size: 3446 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220815/4c57a5a2/attachment.bin>
More information about the llvm-commits
mailing list