diff options
author | 卜部昌平 <[email protected]> | 2019-07-31 23:00:15 +0900 |
---|---|---|
committer | 卜部昌平 <[email protected]> | 2019-08-01 16:00:59 +0900 |
commit | 5d33f787169bcc3594d2264726695d58c4a06899 (patch) | |
tree | f3a4fb4c67a22571d8dd632d4f77c452ecfa8863 /ext/-test-/bug-14834 | |
parent | d2f8e03f346424553f3081896c91dd7d6fdf5db0 (diff) |
fix tracepoint + backtrace SEGV
PC modification in gc_event_hook_body was careless. There are (so
to say) abnormal iseqs stored in the cfp. We have to check sanity
before we touch the PC.
This has not been fixed because there was no way to (ab)use the
setup from pure-Ruby. However by using our official C APIs it is
possible to touch such frame(s), resulting in SEGV.
Fixes [Bug #14834].
Diffstat (limited to 'ext/-test-/bug-14834')
-rw-r--r-- | ext/-test-/bug-14834/bug-14384.c | 35 | ||||
-rw-r--r-- | ext/-test-/bug-14834/depend | 14 | ||||
-rw-r--r-- | ext/-test-/bug-14834/extconf.rb | 2 |
3 files changed, 51 insertions, 0 deletions
diff --git a/ext/-test-/bug-14834/bug-14384.c b/ext/-test-/bug-14834/bug-14384.c new file mode 100644 index 0000000000..58abd6d435 --- /dev/null +++ b/ext/-test-/bug-14834/bug-14384.c @@ -0,0 +1,35 @@ +#include <ruby/ruby.h> +#include <ruby/debug.h> + +static NOINLINE(VALUE f(VALUE)); +static NOINLINE(void g(VALUE, void*)); +extern NOINLINE(void Init_bug_14384(void)); + +void +Init_bug_14834(void) +{ + VALUE q = rb_define_module("Bug"); + rb_define_module_function(q, "bug_14834", f, 0); +} + +VALUE +f(VALUE q) +{ + int w[] = { 0, 1024 }; + VALUE e = rb_tracepoint_new(Qnil, RUBY_INTERNAL_EVENT_NEWOBJ, g, w); + + rb_tracepoint_enable(e); + return rb_ensure(rb_yield, q, rb_tracepoint_disable, e); +} + +void +g(MAYBE_UNUSED(VALUE q), void* w) +{ + const int *e = (const int *)w; + const int r = *e++; + const int t = *e++; + VALUE y[t]; + int u[t]; + + rb_profile_frames(r, t, y, u); +} diff --git a/ext/-test-/bug-14834/depend b/ext/-test-/bug-14834/depend new file mode 100644 index 0000000000..5206f995be --- /dev/null +++ b/ext/-test-/bug-14834/depend @@ -0,0 +1,14 @@ +# AUTOGENERATED DEPENDENCIES START +bug-14384.o: $(RUBY_EXTCONF_H) +bug-14384.o: $(arch_hdrdir)/ruby/config.h +bug-14384.o: $(hdrdir)/ruby/assert.h +bug-14384.o: $(hdrdir)/ruby/backward.h +bug-14384.o: $(hdrdir)/ruby/debug.h +bug-14384.o: $(hdrdir)/ruby/defines.h +bug-14384.o: $(hdrdir)/ruby/intern.h +bug-14384.o: $(hdrdir)/ruby/missing.h +bug-14384.o: $(hdrdir)/ruby/ruby.h +bug-14384.o: $(hdrdir)/ruby/st.h +bug-14384.o: $(hdrdir)/ruby/subst.h +bug-14384.o: bug-14384.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/bug-14834/extconf.rb b/ext/-test-/bug-14834/extconf.rb new file mode 100644 index 0000000000..e8f3f1f437 --- /dev/null +++ b/ext/-test-/bug-14834/extconf.rb @@ -0,0 +1,2 @@ +# frozen_string_literal: true +create_makefile("-test-/bug_14834") |