ruby-changes:55198
From: tenderlove <ko1@a...>
Date: Tue, 2 Apr 2019 07:52:41 +0900 (JST)
Subject: [ruby-changes:55198] tenderlove:r67405 (trunk): unpoison / poison objects while walking the heap
tenderlove 2019-04-02 07:52:35 +0900 (Tue, 02 Apr 2019) New Revision: 67405 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=67405 Log: unpoison / poison objects while walking the heap This fixes some ASAN errors Modified files: trunk/internal.h trunk/iseq.c Index: internal.h =================================================================== --- internal.h (revision 67404) +++ internal.h (revision 67405) @@ -105,6 +105,7 @@ extern "C" { https://github.com/ruby/ruby/blob/trunk/internal.h#L105 # 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) https://github.com/ruby/ruby/blob/trunk/internal.h#L133 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) { Index: iseq.c =================================================================== --- iseq.c (revision 67404) +++ iseq.c (revision 67405) @@ -1011,10 +1011,17 @@ remove_coverage_i(void *vstart, void *ve https://github.com/ruby/ruby/blob/trunk/iseq.c#L1011 { 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, si https://github.com/ruby/ruby/blob/trunk/iseq.c#L3163 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; } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/