diff options
author | tenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2019-04-01 22:52:35 +0000 |
---|---|---|
committer | tenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2019-04-01 22:52:35 +0000 |
commit | 1286674bb9855d69f3448fb76c2721c5ac38b84c (patch) | |
tree | 7843fbcb9e096070fd6417f6bf997e439fb99d7e | |
parent | 990df873029a632c06dee9de9768bda8400fe922 (diff) |
unpoison / poison objects while walking the heap
This fixes some ASAN errors
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67405 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | internal.h | 10 | ||||
-rw-r--r-- | iseq.c | 14 |
2 files changed, 24 insertions, 0 deletions
diff --git a/internal.h b/internal.h index 50a20a2bf6..f2c9c238eb 100644 --- a/internal.h +++ b/internal.h @@ -105,6 +105,7 @@ extern "C" { # define __asan_poison_memory_region(x, y) # define __asan_unpoison_memory_region(x, y) # define __asan_region_is_poisoned(x, y) 0 +# define poisoned_object_p(x) 0 #endif #ifdef HAVE_SANITIZER_MSAN_INTERFACE_H @@ -132,6 +133,15 @@ poison_object(VALUE obj) poison_memory_region(ptr, SIZEOF_VALUE); } +#if __has_feature(address_sanitizer) +static inline void * +poisoned_object_p(VALUE obj) +{ + struct RVALUE *ptr = (void *)obj; + return __asan_region_is_poisoned(ptr, SIZEOF_VALUE); +} +#endif + static inline void unpoison_memory_region(const volatile void *ptr, size_t size, bool malloc_p) { @@ -1011,10 +1011,17 @@ remove_coverage_i(void *vstart, void *vend, size_t stride, void *data) { VALUE v = (VALUE)vstart; for (; v != (VALUE)vend; v += stride) { + void *ptr = poisoned_object_p(v); + unpoison_object(v, false); + if (rb_obj_is_iseq(v)) { rb_iseq_t *iseq = (rb_iseq_t *)v; ISEQ_COVERAGE_SET(iseq, Qnil); } + + if (ptr) { + poison_object(v); + } } return 0; } @@ -3156,9 +3163,16 @@ trace_set_i(void *vstart, void *vend, size_t stride, void *data) VALUE v = (VALUE)vstart; for (; v != (VALUE)vend; v += stride) { + void *ptr = poisoned_object_p(v); + unpoison_object(v, false); + if (rb_obj_is_iseq(v)) { rb_iseq_trace_set(rb_iseq_check((rb_iseq_t *)v), turnon_events); } + + if (ptr) { + poison_object(v); + } } return 0; } |