[PATCH] D69537: [asan] Provide interface to iterate over all Fake stack regions

Johan Engelen via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 28 15:15:23 PDT 2019


johanengelen created this revision.
johanengelen added a reviewer: kcc.
johanengelen added a project: Sanitizers.
Herald added a project: LLVM.
Herald added subscribers: llvm-commits, Sanitizers.

This adds an interface for a program to iterate over all Fake stack regions.
In particular, this enables a garbage collector to correctly observe reference to objects that are on the Fake stack (the normal stack would be scanned, but the Fake stack cannot be scanned without this added interface).

Two functions are added. One to scan only the provided thread ID's Fake stack, and one to scan all Fake stacks for all threads known to ASan.

Currently no test case is included. Please advice on how best to test this and in which file to place the testcases.


Repository:
  rCRT Compiler Runtime

https://reviews.llvm.org/D69537

Files:
  compiler-rt/include/sanitizer/common_interface_defs.h
  compiler-rt/lib/asan/asan_interface.inc
  compiler-rt/lib/asan/asan_thread.cpp


Index: compiler-rt/lib/asan/asan_thread.cpp
===================================================================
--- compiler-rt/lib/asan/asan_thread.cpp
+++ compiler-rt/lib/asan/asan_thread.cpp
@@ -533,4 +533,40 @@
                        (uptr*)bottom_old,
                        (uptr*)size_old);
 }
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_for_each_extra_stack_range(
+    u64 os_id, void (*callback)(uptr begin, uptr end, void *arg), void *arg) {
+  AsanThread *t = GetAsanThreadByOsIDLocked(os_id);
+  if (t && t->has_fake_stack())
+    t->fake_stack()->ForEachFakeFrame(callback, arg);
+}
+
+struct RichRangeIteratorCallback {
+  RangeIteratorCallback callback;
+  void *arg;
+};
+
+static void
+CallRichRangeCallback(ThreadContextBase *tctx_base, void *arg) {
+  auto *cb = reinterpret_cast<RichRangeIteratorCallback *>(arg);
+  auto *tctx = static_cast<AsanThreadContext *>(tctx_base);
+  AsanThread *t = tctx->thread;
+  if (t && t->has_fake_stack())
+    t->fake_stack()->ForEachFakeFrame(cb->callback, cb->arg);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_for_each_extra_stack_range_all_threads(
+    void (*callback)(uptr begin, uptr end, void *arg), void *arg) {
+  if (!__asan_option_detect_stack_use_after_return)
+    return;
+
+  RichRangeIteratorCallback cb = {callback, arg};
+  {
+    ThreadRegistryLock l(&asanThreadRegistry());
+    asanThreadRegistry().RunCallbackForEachThreadLocked(CallRichRangeCallback,
+                                                        &cb);
+  }
 }
+}  // extern "C"
Index: compiler-rt/lib/asan/asan_interface.inc
===================================================================
--- compiler-rt/lib/asan/asan_interface.inc
+++ compiler-rt/lib/asan/asan_interface.inc
@@ -154,6 +154,8 @@
 INTERFACE_FUNCTION(__asan_unregister_image_globals)
 INTERFACE_FUNCTION(__asan_version_mismatch_check_v8)
 INTERFACE_FUNCTION(__sanitizer_finish_switch_fiber)
+INTERFACE_FUNCTION(__sanitizer_for_each_extra_stack_range)
+INTERFACE_FUNCTION(__sanitizer_for_each_extra_stack_range_all_threads)
 INTERFACE_FUNCTION(__sanitizer_print_stack_trace)
 INTERFACE_FUNCTION(__sanitizer_ptr_cmp)
 INTERFACE_FUNCTION(__sanitizer_ptr_sub)
Index: compiler-rt/include/sanitizer/common_interface_defs.h
===================================================================
--- compiler-rt/include/sanitizer/common_interface_defs.h
+++ compiler-rt/include/sanitizer/common_interface_defs.h
@@ -341,6 +341,30 @@
                                      const void **bottom_old,
                                      size_t *size_old);
 
+/// Calls the user-provided <c>callback</c> for each Fake stack region for the
+/// specified thread ID.
+///
+/// \param os_tid Thread ID. Only the Fake stack of this thread ID is considered.
+/// \param callback User-provided callback. For each stack region,
+///                 <c>callback</c> is called with <c>begin</c> and
+///                 <c>end</c> marking the stack span and <c>arg</c>
+///                 equal to the <c>arg</c> parameter value passed.
+/// \param arg This value is passed as last parameter to <c>callback</c>.
+void __sanitizer_for_each_extra_stack_range(
+    uint64_t os_tid, void (*callback)(size_t begin, size_t end, void *arg),
+    void *arg);
+
+/// Calls the user-provided <c>callback</c> for each Fake stack region for
+/// threads that have a Fake stack.
+///
+/// \param callback User-provided callback. For each stack region,
+///                 <c>callback</c> is called with <c>begin</c> and
+///                 <c>end</c> marking the stack span and <c>arg</c>
+///                 equal to the user-provided <c>arg</c> value.
+/// \param arg This value is passed as last parameter to <c>callback</c>.
+void __sanitizer_for_each_extra_stack_range_all_threads(
+    void (*callback)(size_t begin, size_t end, void *arg), void *arg);
+
 // Get full module name and calculate pc offset within it.
 // Returns 1 if pc belongs to some module, 0 if module was not found.
 int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D69537.226755.patch
Type: text/x-patch
Size: 4067 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191028/fd06dc9e/attachment.bin>


More information about the llvm-commits mailing list