1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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].
This commit is contained in:
卜部昌平 2019-07-31 23:00:15 +09:00
parent d2f8e03f34
commit 5d33f78716
5 changed files with 68 additions and 2 deletions

View file

@ -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);
}

View file

@ -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

View file

@ -0,0 +1,2 @@
# frozen_string_literal: true
create_makefile("-test-/bug_14834")

7
gc.c
View file

@ -1925,8 +1925,11 @@ rb_objspace_set_event_hook(const rb_event_flag_t event)
static void
gc_event_hook_body(rb_execution_context_t *ec, rb_objspace_t *objspace, const rb_event_flag_t event, VALUE data)
{
/* increment PC because source line is calculated with PC-1 */
const VALUE *pc = ec->cfp->pc++;
const VALUE *pc = ec->cfp->pc;
if (VM_FRAME_RUBYFRAME_P(ec->cfp)) {
/* increment PC because source line is calculated with PC-1 */
ec->cfp->pc++;
}
EXEC_EVENT_HOOK(ec, event, ec->cfp->self, 0, 0, 0, data);
ec->cfp->pc = pc;
}

View file

@ -0,0 +1,12 @@
# frozen_string_literal: true
class Test_BUG_14834 < Test::Unit::TestCase
def test
assert_ruby_status [], <<~'end;', '[ruby-core:87449] [Bug #14834]'
require '-test-/bug_14834'
Bug.bug_14834 do
[123].group_by {}
end
end;
end
end