Skip to content

Commit 533fef0

Browse files
committed
Add compatibility checks for rb_profile_frames.
On ruby < 3.0 rb_profile_frames omits c frames so we cannot use it to get frame_depth. On ruby < 3.2.0 it adds an extra dummy frame in the output that must be accounted for.
1 parent 72cd0ee commit 533fef0

File tree

3 files changed

+66
-42
lines changed

3 files changed

+66
-42
lines changed

ext/debug/debug.c

Lines changed: 15 additions & 1 deletion
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -89,6 +89,7 @@ capture_frames(VALUE self, VALUE skip_path_prefix)
89
return rb_debug_inspector_open(di_body, (void *)skip_path_prefix);
89
return rb_debug_inspector_open(di_body, (void *)skip_path_prefix);
90
}
90
}
91

91

92+
#ifdef RB_PROFILE_FRAMES_HAS_C_FRAMES
92
#define BUFF_SIZE 4096
93
#define BUFF_SIZE 4096
93

94

94
static VALUE
95
static VALUE
@@ -109,8 +110,21 @@ frame_depth(VALUE self)
109

110

110
// rb_profile_frames will return one extra frame
111
// rb_profile_frames will return one extra frame
111
// https://bugs.ruby-lang.org/issues/18907
112
// https://bugs.ruby-lang.org/issues/18907
112-
return INT2FIX(size - 1);
113+
#ifdef RB_PROFILE_FRAMES_HAS_EXTRA_FRAME
114+
return INT2FIX(size - 1);
115+
#else
116+
return INT2FIX(size);
117+
#endif
118+
}
119+
#else
120+
static VALUE
121+
frame_depth(VALUE self)
122+
{
123+
// TODO: more efficient API
124+
VALUE bt = rb_make_backtrace();
125+
return INT2FIX(RARRAY_LEN(bt));
113
}
126
}
127+
#endif
114

128

115
// iseq
129
// iseq
116

130

ext/debug/extconf.rb

Lines changed: 8 additions & 0 deletions
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -7,8 +7,16 @@
7
$defs << '-DHAVE_RB_ISEQ_PARAMETERS'
7
$defs << '-DHAVE_RB_ISEQ_PARAMETERS'
8
$defs << '-DHAVE_RB_ISEQ_CODE_LOCATION'
8
$defs << '-DHAVE_RB_ISEQ_CODE_LOCATION'
9

9

10+
if RUBY_VERSION >= '3.0.0'
11+
$defs << '-DRB_PROFILE_FRAMES_HAS_C_FRAMES'
12+
end
13+
10
if RUBY_VERSION >= '3.1.0'
14
if RUBY_VERSION >= '3.1.0'
11
$defs << '-DHAVE_RB_ISEQ_TYPE'
15
$defs << '-DHAVE_RB_ISEQ_TYPE'
16+
17+
if RUBY_VERSION < '3.2.0'
18+
$defs << '-DRB_PROFILE_FRAMES_HAS_EXTRA_FRAME'
19+
end
12
end
20
end
13
else
21
else
14
# not on MRI
22
# not on MRI

test/console/control_flow_commands_test.rb

Lines changed: 43 additions & 41 deletions
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -363,48 +363,50 @@ def test_next_steps_over_rescue_when_raising_from_method
363
# Tests that next/finish work for a deep call stack.
363
# Tests that next/finish work for a deep call stack.
364
# We use different logic for computing frame depth when the call stack is above/below 4096.
364
# We use different logic for computing frame depth when the call stack is above/below 4096.
365
#
365
#
366-
class DeepCallstackTest < ConsoleTestCase
366+
if RUBY_VERSION >= '3.0.0'
367-
def program
367+
class DeepCallstackTest < ConsoleTestCase
368-
<<~RUBY
368+
def program
369-
1| # target.rb
369+
<<~RUBY
370-
2| def foo
370+
1| # target.rb
371-
3| "hello"
371+
2| def foo
372-
4| end
372+
3| "hello"
373-
5|
373+
4| end
374-
6| def recursive(n,stop)
374+
5|
375-
7| foo
375+
6| def recursive(n,stop)
376-
8| return if n >= stop
376+
7| foo
377-
9|
377+
8| return if n >= stop
378-
10| recursive(n + 1, stop)
378+
9|
379-
11| end
379+
10| recursive(n + 1, stop)
380-
12|
380+
11| end
381-
13| recursive(0, 4100)
381+
12|
382-
14|
382+
13| recursive(0, 4100)
383-
15| "done"
383+
14|
384-
RUBY
384+
15| "done"
385-
end
385+
RUBY
386-
387-
def test_next
388-
debug_code(program) do
389-
type 'b 13'
390-
type 'c'
391-
assert_line_num 13
392-
type 'n'
393-
assert_line_num 15
394-
type 'q!'
395
end
386
end
396-
end
387+
397-
388+
def test_next
398-
def test_finish
389+
debug_code(program) do
399-
debug_code(program) do
390+
type 'b 13'
400-
type 'b 13'
391+
type 'c'
401-
type 'c'
392+
assert_line_num 13
402-
assert_line_num 13
393+
type 'n'
403-
type 's'
394+
assert_line_num 15
404-
assert_line_num 7
395+
type 'q!'
405-
type 'fin'
396+
end
406-
assert_line_num 11
397+
end
407-
type 'q!'
398+
399+
def test_finish
400+
debug_code(program) do
401+
type 'b 13'
402+
type 'c'
403+
assert_line_num 13
404+
type 's'
405+
assert_line_num 7
406+
type 'fin'
407+
assert_line_num 11
408+
type 'q!'
409+
end
408
end
410
end
409
end
411
end
410
end
412
end

0 commit comments

Comments
 (0)