[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