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:
parent
976b6df959
commit
3b7373fd00
@ -990,4 +990,31 @@ class TestMethod < Test::Unit::TestCase
|
|||||||
assert_equal('1', obj.foo(1))
|
assert_equal('1', obj.foo(1))
|
||||||
assert_equal('1', obj.bar(1))
|
assert_equal('1', obj.bar(1))
|
||||||
end
|
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
|
end
|
||||||
|
@ -687,6 +687,8 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co
|
|||||||
return opt_pc;
|
return opt_pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rb_backtrace_use_iseq_first_lineno_for_last_location(VALUE self); /* vm_backtrace.c */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
raise_argument_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const VALUE exc)
|
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,
|
iseq->body->iseq_encoded,
|
||||||
ec->cfp->sp, 0, 0 /* stack_max */);
|
ec->cfp->sp, 0, 0 /* stack_max */);
|
||||||
at = rb_ec_backtrace_object(ec);
|
at = rb_ec_backtrace_object(ec);
|
||||||
|
rb_backtrace_use_iseq_first_lineno_for_last_location(at);
|
||||||
rb_vm_pop_frame(ec);
|
rb_vm_pop_frame(ec);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -585,6 +585,25 @@ rb_backtrace_to_str_ary(VALUE self)
|
|||||||
return bt->strary;
|
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
|
static VALUE
|
||||||
location_create(rb_backtrace_location_t *srcloc, void *btobj)
|
location_create(rb_backtrace_location_t *srcloc, void *btobj)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user