[PATCH] D48127: Add new asan_option: paranoid_stack_cmp

wenduo via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 13 07:32:10 PDT 2018


wenduo created this revision.
wenduo added reviewers: morehouse, kcc.
Herald added subscribers: llvm-commits, kubamracek.

This patch add a new asan_option : paranoid_stack_cmp (default true).  See discuss on: https://github.com/google/sanitizers/issues/797

Now, in hot function StackDepotPut,  asan compares stack trace frame by frame even if stack trace's hash are the same. If user's program have a lof of malloc/free ,this operation consumes make  cpu usage really high.  Adjusting malloc_conext_size to 3(or 0) will help, but  also destory the power to report bugs.

If two stacktrace's hash are the same,  they are  very likely to be the same.So comparing stacktrace frame by frame is a bit paranoid.

New option paranoid_stack_cmp offer user a method to  turn on/turn off  frame comparation. So user can trade off between cpu usage and 100% correctness 
This option is on  by default to keep consistent with raw version.


Repository:
  rL LLVM

https://reviews.llvm.org/D48127

Files:
  include/sanitizer/common_interface_defs.h
  lib/asan/asan_rtl.cc
  lib/sanitizer_common/sanitizer_common_interface.inc
  lib/sanitizer_common/sanitizer_flags.inc
  lib/sanitizer_common/sanitizer_interface_internal.h
  lib/sanitizer_common/sanitizer_stackdepot.cc


Index: lib/sanitizer_common/sanitizer_stackdepot.cc
===================================================================
--- lib/sanitizer_common/sanitizer_stackdepot.cc
+++ lib/sanitizer_common/sanitizer_stackdepot.cc
@@ -18,6 +18,8 @@
 
 namespace __sanitizer {
 
+static atomic_uint8_t paranoid_stack_cmp;
+
 struct StackDepotNode {
   StackDepotNode *link;
   u32 id;
@@ -40,6 +42,8 @@
         atomic_load(&hash_and_use_count, memory_order_relaxed) & kHashMask;
     if ((hash & kHashMask) != hash_bits || args.size != size || args.tag != tag)
       return false;
+    if (!atomic_load(&paranoid_stack_cmp, memory_order_acquire))
+        return true;
     uptr i = 0;
     for (; i < size; i++) {
       if (stack[i] != args.trace[i]) return false;
@@ -161,3 +165,11 @@
 }
 
 } // namespace __sanitizer
+
+using namespace __sanitizer;  // NOLINT
+
+extern "C" {
+void __sanitizer_set_stack_cmp(bool do_cmp) {
+  atomic_store(&paranoid_stack_cmp, do_cmp, memory_order_release);
+}
+} // extern "C"
Index: lib/sanitizer_common/sanitizer_interface_internal.h
===================================================================
--- lib/sanitizer_common/sanitizer_interface_internal.h
+++ lib/sanitizer_common/sanitizer_interface_internal.h
@@ -30,6 +30,9 @@
   SANITIZER_INTERFACE_ATTRIBUTE
   void __sanitizer_set_report_fd(void *fd);
 
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __sanitizer_set_stack_cmp(bool do_cmp);
+
   typedef struct {
       int coverage_sandboxed;
       __sanitizer::sptr coverage_fd;
Index: lib/sanitizer_common/sanitizer_flags.inc
===================================================================
--- lib/sanitizer_common/sanitizer_flags.inc
+++ lib/sanitizer_common/sanitizer_flags.inc
@@ -47,6 +47,8 @@
 COMMON_FLAG(bool, handle_ioctl, false, "Intercept and handle ioctl requests.")
 COMMON_FLAG(int, malloc_context_size, 1,
             "Max number of stack frames kept for each allocation/deallocation.")
+COMMON_FLAG(bool, paranoid_stack_cmp, true,
+            "If true, examine stack frame by frame paranoidly for each allocation/deallocation.")
 COMMON_FLAG(
     const char *, log_path, "stderr",
     "Write logs to \"log_path.pid\". The special values are \"stdout\" and "
Index: lib/sanitizer_common/sanitizer_common_interface.inc
===================================================================
--- lib/sanitizer_common/sanitizer_common_interface.inc
+++ lib/sanitizer_common/sanitizer_common_interface.inc
@@ -14,6 +14,7 @@
 INTERFACE_FUNCTION(__sanitizer_set_death_callback)
 INTERFACE_FUNCTION(__sanitizer_set_report_path)
 INTERFACE_FUNCTION(__sanitizer_set_report_fd)
+INTERFACE_FUNCTION(__sanitizer_set_stack_cmp)
 INTERFACE_FUNCTION(__sanitizer_verify_contiguous_container)
 INTERFACE_WEAK_FUNCTION(__sanitizer_report_error_summary)
 INTERFACE_WEAK_FUNCTION(__sanitizer_sandbox_on_notify)
Index: lib/asan/asan_rtl.cc
===================================================================
--- lib/asan/asan_rtl.cc
+++ lib/asan/asan_rtl.cc
@@ -396,6 +396,7 @@
 
   SetCanPoisonMemory(flags()->poison_heap);
   SetMallocContextSize(common_flags()->malloc_context_size);
+  __sanitizer_set_stack_cmp(common_flags()->paranoid_stack_cmp);
 
   InitializePlatformExceptionHandlers();
 
Index: include/sanitizer/common_interface_defs.h
===================================================================
--- include/sanitizer/common_interface_defs.h
+++ include/sanitizer/common_interface_defs.h
@@ -45,6 +45,7 @@
   // (casted to void *).
   void __sanitizer_set_report_fd(void *fd);
 
+  void __sanitizer_set_stack_cmp(bool do_cmp);
   // Notify the tools that the sandbox is going to be turned on. The reserved
   // parameter will be used in the future to hold a structure with functions
   // that the tools may call to bypass the sandbox.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48127.151155.patch
Type: text/x-patch
Size: 3788 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180613/803238d5/attachment.bin>


More information about the llvm-commits mailing list