Previously, Ruby displayed backtraces for each thread on deadlock. However, it has not been shown since Ruby 3.0. It should display the backtrace for debugging. Co-authored-by: Jeremy Evans <code@jeremyevans.net>
This commit is contained in:
parent
b4ed6db096
commit
0cab608d3a
Notes:
git
2025-02-14 07:32:15 +00:00
Merged-By: pocke <p.ck.t22@gmail.com>
@ -300,6 +300,8 @@ void rb_vm_set_progname(VALUE filename);
|
||||
VALUE rb_vm_cbase(void);
|
||||
|
||||
/* vm_backtrace.c */
|
||||
#define RUBY_BACKTRACE_START 0
|
||||
#define RUBY_ALL_BACKTRACE_LINES -1
|
||||
VALUE rb_ec_backtrace_object(const rb_execution_context_t *ec);
|
||||
VALUE rb_ec_backtrace_str_ary(const rb_execution_context_t *ec, long lev, long n);
|
||||
VALUE rb_ec_backtrace_location_ary(const rb_execution_context_t *ec, long lev, long n, bool skip_internal);
|
||||
|
@ -1553,4 +1553,36 @@ q.pop
|
||||
assert_equal(true, t.pending_interrupt?(Exception))
|
||||
assert_equal(false, t.pending_interrupt?(ArgumentError))
|
||||
end
|
||||
|
||||
def test_deadlock_backtrace
|
||||
bug21127 = '[ruby-core:120930] [Bug #21127]'
|
||||
|
||||
expected_stderr = [
|
||||
/-:12:in 'Thread#join': No live threads left. Deadlock\? \(fatal\)\n/,
|
||||
/2 threads, 2 sleeps current:\w+ main thread:\w+\n/,
|
||||
/\* #<Thread:\w+ sleep_forever>\n/,
|
||||
:*,
|
||||
/^\s*-:6:in 'Object#frame_for_deadlock_test_2'/,
|
||||
:*,
|
||||
/\* #<Thread:\w+ -:10 sleep_forever>\n/,
|
||||
:*,
|
||||
/^\s*-:2:in 'Object#frame_for_deadlock_test_1'/,
|
||||
:*,
|
||||
]
|
||||
|
||||
assert_in_out_err([], <<-INPUT, [], expected_stderr, bug21127)
|
||||
def frame_for_deadlock_test_1
|
||||
yield
|
||||
end
|
||||
|
||||
def frame_for_deadlock_test_2
|
||||
yield
|
||||
end
|
||||
|
||||
q = Thread::Queue.new
|
||||
t = Thread.new { frame_for_deadlock_test_1 { q.pop } }
|
||||
|
||||
frame_for_deadlock_test_2 { t.join }
|
||||
INPUT
|
||||
end
|
||||
end
|
||||
|
2
thread.c
2
thread.c
@ -5588,7 +5588,7 @@ debug_deadlock_check(rb_ractor_t *r, VALUE msg)
|
||||
}
|
||||
}
|
||||
rb_str_catf(msg, "\n ");
|
||||
rb_str_concat(msg, rb_ary_join(rb_ec_backtrace_str_ary(th->ec, 0, 0), sep));
|
||||
rb_str_concat(msg, rb_ary_join(rb_ec_backtrace_str_ary(th->ec, RUBY_BACKTRACE_START, RUBY_ALL_BACKTRACE_LINES), sep));
|
||||
rb_str_catf(msg, "\n");
|
||||
}
|
||||
}
|
||||
|
@ -31,9 +31,6 @@ id2str(ID id)
|
||||
}
|
||||
#define rb_id2str(id) id2str(id)
|
||||
|
||||
#define BACKTRACE_START 0
|
||||
#define ALL_BACKTRACE_LINES -1
|
||||
|
||||
inline static int
|
||||
calc_pos(const rb_iseq_t *iseq, const VALUE *pc, int *lineno, int *node_id)
|
||||
{
|
||||
@ -758,7 +755,7 @@ rb_ec_partial_backtrace_object(const rb_execution_context_t *ec, long start_fram
|
||||
VALUE
|
||||
rb_ec_backtrace_object(const rb_execution_context_t *ec)
|
||||
{
|
||||
return rb_ec_partial_backtrace_object(ec, BACKTRACE_START, ALL_BACKTRACE_LINES, NULL, FALSE, FALSE);
|
||||
return rb_ec_partial_backtrace_object(ec, RUBY_BACKTRACE_START, RUBY_ALL_BACKTRACE_LINES, NULL, FALSE, FALSE);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
@ -1191,7 +1188,7 @@ rb_backtrace_each(VALUE (*iter)(VALUE recv, VALUE str), VALUE output)
|
||||
VALUE
|
||||
rb_make_backtrace(void)
|
||||
{
|
||||
return rb_ec_backtrace_str_ary(GET_EC(), BACKTRACE_START, ALL_BACKTRACE_LINES);
|
||||
return rb_ec_backtrace_str_ary(GET_EC(), RUBY_BACKTRACE_START, RUBY_ALL_BACKTRACE_LINES);
|
||||
}
|
||||
|
||||
static long
|
||||
@ -1210,7 +1207,7 @@ ec_backtrace_range(const rb_execution_context_t *ec, int argc, const VALUE *argv
|
||||
switch (argc) {
|
||||
case 0:
|
||||
lev = lev_default + lev_plus;
|
||||
n = ALL_BACKTRACE_LINES;
|
||||
n = RUBY_ALL_BACKTRACE_LINES;
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
@ -1222,7 +1219,7 @@ ec_backtrace_range(const rb_execution_context_t *ec, int argc, const VALUE *argv
|
||||
rb_raise(rb_eArgError, "negative level (%ld)", lev);
|
||||
}
|
||||
lev += lev_plus;
|
||||
n = ALL_BACKTRACE_LINES;
|
||||
n = RUBY_ALL_BACKTRACE_LINES;
|
||||
break;
|
||||
case Qnil:
|
||||
return -1;
|
||||
@ -1626,7 +1623,7 @@ rb_debug_inspector_open(rb_debug_inspector_func_t func, void *data)
|
||||
|
||||
dbg_context.ec = ec;
|
||||
dbg_context.cfp = dbg_context.ec->cfp;
|
||||
dbg_context.backtrace = rb_ec_backtrace_location_ary(ec, BACKTRACE_START, ALL_BACKTRACE_LINES, FALSE);
|
||||
dbg_context.backtrace = rb_ec_backtrace_location_ary(ec, RUBY_BACKTRACE_START, RUBY_ALL_BACKTRACE_LINES, FALSE);
|
||||
dbg_context.backtrace_size = RARRAY_LEN(dbg_context.backtrace);
|
||||
dbg_context.contexts = collect_caller_bindings(ec);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user