diff --git a/test/ruby/test_backtrace.rb b/test/ruby/test_backtrace.rb index fca7b620302680..3752e4853bb74b 100644 --- a/test/ruby/test_backtrace.rb +++ b/test/ruby/test_backtrace.rb @@ -328,7 +328,7 @@ def test_thread_backtrace th_backtrace = th.backtrace th_locations = th.backtrace_locations - assert_equal(10, th_backtrace.count{|e| e =~ /th_rec/}) + assert_equal(11, th_backtrace.count{|e| e =~ /th_rec/}) assert_equal(th_backtrace, th_locations.map{|e| e.to_s}) assert_equal(th_backtrace, th.backtrace(0)) assert_equal(th_locations.map{|e| e.to_s}, diff --git a/vm_backtrace.c b/vm_backtrace.c index 26e0a6fb76f393..310f6fa25400a2 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -262,6 +262,8 @@ calculate_iseq_label(VALUE owner, const rb_iseq_t *iseq) } } +static bool is_internal_iseq(const rb_iseq_t *iseq); + // Return true if a given location is a C method or supposed to behave like one. static inline bool location_cfunc_p(rb_backtrace_location_t *loc) @@ -272,7 +274,7 @@ location_cfunc_p(rb_backtrace_location_t *loc) case VM_METHOD_TYPE_CFUNC: return true; case VM_METHOD_TYPE_ISEQ: - return rb_iseq_attr_p(loc->cme->def->body.iseq.iseqptr, BUILTIN_ATTR_C_TRACE); + return is_internal_iseq(loc->cme->def->body.iseq.iseqptr); default: return false; } @@ -606,10 +608,16 @@ backtrace_size(const rb_execution_context_t *ec) static bool is_internal_location(const rb_control_frame_t *cfp) +{ + return is_internal_iseq(cfp->iseq); +} + +static bool +is_internal_iseq(const rb_iseq_t *iseq) { static const char prefix[] = "iseq); + VALUE file = rb_iseq_path(iseq); return strncmp(prefix, RSTRING_PTR(file), prefix_len) == 0; } @@ -698,7 +706,7 @@ rb_ec_partial_backtrace_object(const rb_execution_context_t *ec, long start_fram loc = &bt->backtrace[bt->backtrace_size++]; RB_OBJ_WRITE(btobj, &loc->cme, rb_vm_frame_method_entry(cfp)); // Ruby methods with `Primitive.attr! :c_trace` should behave like C methods - if (rb_iseq_attr_p(cfp->iseq, BUILTIN_ATTR_C_TRACE)) { + if (is_internal_location(cfp)) { loc->iseq = NULL; loc->pc = NULL; cfunc_counter++;