Skip to content

Commit e83ba4f

Browse files
committed
use rb_profile_frames for frame_depth
1 parent 2cb4448 commit e83ba4f

File tree

2 files changed

+65
-3
lines changed

2 files changed

+65
-3
lines changed

ext/debug/debug.c

Lines changed: 15 additions & 3 deletions
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -89,12 +89,24 @@ 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+
#define BUFF_SIZE 4096
93+
92
static VALUE
94
static VALUE
93
frame_depth(VALUE self)
95
frame_depth(VALUE self)
94
{
96
{
95-
// TODO: more efficient API
97+
static VALUE buff[BUFF_SIZE];
96-
VALUE bt = rb_make_backtrace();
98+
static int lines[BUFF_SIZE];
97-
return INT2FIX(RARRAY_LEN(bt));
99+
100+
int size = rb_profile_frames(0, BUFF_SIZE, buff, lines);
101+
102+
// If the buffer is full, there might be more frames.
103+
// Fall back to rb_make_backtrace to get them all.
104+
if (size >= BUFF_SIZE) {
105+
VALUE bt = rb_make_backtrace();
106+
size = RARRAY_LEN(bt);
107+
}
108+
109+
return INT2FIX(size);
98
}
110
}
99

111

100
// iseq
112
// iseq

test/console/control_flow_commands_test.rb

Lines changed: 50 additions & 0 deletions
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -358,4 +358,54 @@ def test_next_steps_over_rescue_when_raising_from_method
358
end
358
end
359
end
359
end
360
end
360
end
361+
362+
#
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.
365+
#
366+
class DeepCallstackTest < ConsoleTestCase
367+
def program
368+
<<~RUBY
369+
1| # target.rb
370+
2| def foo
371+
3| "hello"
372+
4| end
373+
5|
374+
6| def recursive(n,stop)
375+
7| foo
376+
8| return if n >= stop
377+
9|
378+
10| recursive(n + 1, stop)
379+
11| end
380+
12|
381+
13| recursive(0, 4100)
382+
14|
383+
15| "done"
384+
RUBY
385+
end
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
396+
end
397+
398+
def test_finish
399+
debug_code(program) do
400+
type 'b 13'
401+
type 'c'
402+
assert_line_num 13
403+
type 's'
404+
assert_line_num 7
405+
type 'fin'
406+
assert_line_num 11
407+
type 'q!'
408+
end
409+
end
410+
end
361
end
411
end

0 commit comments

Comments
 (0)