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

fix backtrace on argment error.

* vm_backtrace.c (rb_backtrace_use_iseq_first_lineno_for_last_location):
  added. It modifies last location's line as corresponding iseq's first line
  number.

* vm_args.c (raise_argument_error): use added function.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60725 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2017-11-09 05:22:51 +00:00
parent 976b6df959
commit 3b7373fd00
3 changed files with 49 additions and 0 deletions

View file

@ -990,4 +990,31 @@ class TestMethod < Test::Unit::TestCase
assert_equal('1', obj.foo(1))
assert_equal('1', obj.bar(1))
end
def test_argument_error_location
body = <<-'END_OF_BODY'
eval <<-'EOS'
$line_lambda = __LINE__; $f = lambda do
_x = 1
end
$line_method = __LINE__; def foo
_x = 1
end
begin
$f.call(1)
rescue ArgumentError => e
assert_equal "(eval):#{$line_lambda.to_s}:in `block in <main>'", e.backtrace.first
end
begin
foo(1)
rescue ArgumentError => e
assert_equal "(eval):#{$line_method}:in `foo'", e.backtrace.first
end
EOS
END_OF_BODY
assert_separately [], body
# without trace insn
assert_separately [], "RubyVM::InstructionSequence.compile_option = {trace_instruction: false}\n" + body
end
end

View file

@ -687,6 +687,8 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co
return opt_pc;
}
void rb_backtrace_use_iseq_first_lineno_for_last_location(VALUE self); /* vm_backtrace.c */
static void
raise_argument_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const VALUE exc)
{
@ -698,6 +700,7 @@ raise_argument_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const VA
iseq->body->iseq_encoded,
ec->cfp->sp, 0, 0 /* stack_max */);
at = rb_ec_backtrace_object(ec);
rb_backtrace_use_iseq_first_lineno_for_last_location(at);
rb_vm_pop_frame(ec);
}
else {

View file

@ -585,6 +585,25 @@ rb_backtrace_to_str_ary(VALUE self)
return bt->strary;
}
void
rb_backtrace_use_iseq_first_lineno_for_last_location(VALUE self)
{
const rb_backtrace_t *bt;
const rb_iseq_t *iseq;
rb_backtrace_location_t *loc;
GetCoreDataFromValue(self, rb_backtrace_t, bt);
VM_ASSERT(bt->backtrace_size > 0);
loc = &bt->backtrace[bt->backtrace_size - 1];
iseq = loc->body.iseq.iseq;
VM_ASSERT(loc->type == LOCATION_TYPE_ISEQ);
loc->body.iseq.lineno.lineno = FIX2INT(iseq->body->location.first_lineno);
loc->type = LOCATION_TYPE_ISEQ_CALCED;
}
static VALUE
location_create(rb_backtrace_location_t *srcloc, void *btobj)
{