Skip to content

Commit 296daa6

Browse files
committed
Improve method breakpoint performance.
With pending method breakpoints, track all method invocation to track `method_added` and `singleton_method_added`. Of course, this approach slows down the debuggee's performance. This patch tracks all `method_added` and `singleton_method_added` methods and further defined such methods for the classes/modules. This approach doesn't have performance penalty any more. This patch also fix the message at registering the pending method breakpoint. ```ruby binding.b do: 'b C#foo' unless ENV['NO_PENDING_BP'] def fib n if n<2 n else fib(n-1)+fib(n-2) end end require 'benchmark' Benchmark.bm{|x| x.report{ fib(35) } } ``` Results: ``` Without pending breakpoints: $ NO_PENDING_BP=1 exe/rdbg -n target.rb user system total real 0.929580 0.000000 0.929580 ( 0.929682) With pending breakpoints - Before this patch: $ exe/rdbg -n target.rb [1, 10] in target.rb => 1| binding.b do: <<~DBG 2| b C#foo 3| DBG 4| 5| def fib n 6| if n<2 7| n 8| else 9| fib(n-1)+fib(n-2) 10| end =>#0 <main> at target.rb:1 (rdbg:binding.break) b C#foo uninitialized constant C C ^ user system total real 3.276217 0.000000 3.276217 ( 3.276299) With pending breakpoints - After this patch: [master]$ exe/rdbg -n target.rb [1, 10] in target.rb => 1| binding.b do: <<~DBG 2| b C#foo 3| DBG 4| 5| def fib n 6| if n<2 7| n 8| else 9| fib(n-1)+fib(n-2) 10| end =>#0 <main> at target.rb:1 (rdbg:binding.break) b C#foo Unknown name `C` for `Object` user system total real 0.933402 0.002353 0.935755 ( 0.935757) ```
1 parent c35bd4c commit 296daa6

File tree

3 files changed

+48
-42
lines changed

3 files changed

+48
-42
lines changed

ext/debug/debug.c

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -97,27 +97,6 @@ frame_depth(VALUE self)
9797
return INT2FIX(RARRAY_LEN(bt));
9898
}
9999

100-
static void
101-
method_added_tracker(VALUE tpval, void *ptr)
102-
{
103-
rb_trace_arg_t *arg = rb_tracearg_from_tracepoint(tpval);
104-
VALUE mid = rb_tracearg_callee_id(arg);
105-
106-
if (RB_UNLIKELY(mid == ID2SYM(rb_intern("method_added")) ||
107-
mid == ID2SYM(rb_intern("singleton_method_added")))) {
108-
VALUE args[] = {
109-
tpval,
110-
};
111-
rb_funcallv(rb_mDebugger, rb_intern("method_added"), 1, args);
112-
}
113-
}
114-
115-
static VALUE
116-
create_method_added_tracker(VALUE self)
117-
{
118-
return rb_tracepoint_new(0, RUBY_EVENT_CALL, method_added_tracker, NULL);
119-
}
120-
121100
// iseq
122101

123102
const struct rb_iseq *rb_iseqw_to_iseq(VALUE iseqw);
@@ -203,7 +182,6 @@ Init_debug(void)
203182
rb_gc_register_mark_object(rb_cFrameInfo);
204183
rb_define_singleton_method(rb_mDebugger, "capture_frames", capture_frames, 1);
205184
rb_define_singleton_method(rb_mDebugger, "frame_depth", frame_depth, 0);
206-
rb_define_singleton_method(rb_mDebugger, "create_method_added_tracker", create_method_added_tracker, 0);
207185
rb_define_const(rb_mDebugger, "SO_VERSION", rb_str_new2(RUBY_DEBUG_VERSION));
208186

209187
// iseq

lib/debug/session.rb

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1643,7 +1643,7 @@ def method_added tp
16431643
b = tp.binding
16441644
if var_name = b.local_variables.first
16451645
mid = b.local_variable_get(var_name)
1646-
unresolved = false
1646+
resolved = true
16471647

16481648
@bps.each{|k, bp|
16491649
case bp
@@ -1654,15 +1654,53 @@ def method_added tp
16541654
end
16551655
end
16561656

1657-
unresolved = true unless bp.enabled?
1657+
resolved = false if !bp.enabled?
16581658
end
16591659
}
1660-
unless unresolved
1661-
METHOD_ADDED_TRACKER.disable
1660+
1661+
if resolved
1662+
Session.deactivate_method_added_trackers
1663+
end
1664+
1665+
case mid
1666+
when :method_added, :singleton_method_added
1667+
Session.create_method_added_tracker(tp.self, mid)
1668+
Session.create_method_added_tracker unless resolved
16621669
end
16631670
end
16641671
end
16651672

1673+
class ::Module
1674+
undef method_added
1675+
def method_added mid; end
1676+
def singleton_method_added mid; end
1677+
end
1678+
1679+
def self.create_method_added_tracker mod, method_added_id, method_accessor = :method
1680+
m = mod.__send__(method_accessor, method_added_id)
1681+
METHOD_ADDED_TRACKERS[m] = TracePoint.new(:call) do |tp|
1682+
SESSION.method_added tp
1683+
end
1684+
end
1685+
1686+
def self.activate_method_added_trackers
1687+
METHOD_ADDED_TRACKERS.each do |m, tp|
1688+
tp.enable(target: m) unless tp.enabled?
1689+
rescue ArgumentError
1690+
DEBUGGER__.warn "Methods defined under #{m.owner} can not track by the debugger."
1691+
end
1692+
end
1693+
1694+
def self.deactivate_method_added_trackers
1695+
METHOD_ADDED_TRACKERS.each do |m, tp|
1696+
tp.disable if tp.enabled?
1697+
end
1698+
end
1699+
1700+
METHOD_ADDED_TRACKERS = Hash.new
1701+
create_method_added_tracker Module, :method_added, :instance_method
1702+
create_method_added_tracker Module, :singleton_method_added, :instance_method
1703+
16661704
def width
16671705
@ui.width
16681706
end
@@ -2076,21 +2114,8 @@ def self.load_rc
20762114
end
20772115
end
20782116

2079-
class ::Module
2080-
undef method_added
2081-
def method_added mid; end
2082-
def singleton_method_added mid; end
2083-
end
2084-
2085-
def self.method_added tp
2086-
begin
2087-
SESSION.method_added tp
2088-
rescue Exception => e
2089-
p e
2090-
end
2091-
end
2092-
2093-
METHOD_ADDED_TRACKER = self.create_method_added_tracker
2117+
# Inspector
2118+
20942119
SHORT_INSPECT_LENGTH = 40
20952120

20962121
class LimitedPP

lib/debug/thread_client.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -744,9 +744,12 @@ def make_breakpoint args
744744
bp = MethodBreakpoint.new(current_frame.eval_binding, klass_name, op, method_name, cond: cond, command: cmd, path: path)
745745
begin
746746
bp.enable
747+
rescue NameError => e
748+
puts "Unknown name `#{e.name}` for `#{e.receiver}`"
749+
# TODO: Ractor support
750+
Session.activate_method_added_trackers
747751
rescue Exception => e
748752
puts e.message
749-
::DEBUGGER__::METHOD_ADDED_TRACKER.enable
750753
end
751754

752755
bp

0 commit comments

Comments
 (0)