Memory leak with TracePoint on bmethod
[Bug #20194] When disabling the TracePoint on bmethod, the hooks list is not freed. For example: obj = Object.new obj.define_singleton_method(:foo) {} bmethod = obj.method(:foo) tp = TracePoint.new(:return) {} 10.times do 100_000.times do tp.enable(target: bmethod) {} end puts `ps -o rss= -p #{$$}` end Before: 18208 22832 26528 29728 34000 37776 40864 44400 47680 51504 After: 16688 17168 17168 17248 17696 17760 17824 17824 17856 17920
This commit is contained in:
parent
7cf74a2ff2
commit
b14674b236
@ -625,6 +625,19 @@ PREP
|
|||||||
CODE
|
CODE
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_tracepoint_bmethod_memory_leak
|
||||||
|
assert_no_memory_leak([], '', "#{<<~"begin;"}\n#{<<~'end;'}", "[Bug #20194]", rss: true)
|
||||||
|
obj = Object.new
|
||||||
|
obj.define_singleton_method(:foo) {}
|
||||||
|
bmethod = obj.method(:foo)
|
||||||
|
tp = TracePoint.new(:return) {}
|
||||||
|
begin;
|
||||||
|
1_000_000.times do
|
||||||
|
tp.enable(target: bmethod) {}
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
|
||||||
def trace_by_set_trace_func
|
def trace_by_set_trace_func
|
||||||
events = []
|
events = []
|
||||||
trace = nil
|
trace = nil
|
||||||
|
@ -1259,6 +1259,7 @@ rb_tracepoint_enable_for_target(VALUE tpval, VALUE target, VALUE target_line)
|
|||||||
(tp->events & (RUBY_EVENT_CALL | RUBY_EVENT_RETURN))) {
|
(tp->events & (RUBY_EVENT_CALL | RUBY_EVENT_RETURN))) {
|
||||||
if (def->body.bmethod.hooks == NULL) {
|
if (def->body.bmethod.hooks == NULL) {
|
||||||
def->body.bmethod.hooks = ZALLOC(rb_hook_list_t);
|
def->body.bmethod.hooks = ZALLOC(rb_hook_list_t);
|
||||||
|
def->body.bmethod.hooks->is_local = true;
|
||||||
}
|
}
|
||||||
rb_hook_list_connect_tracepoint(target, def->body.bmethod.hooks, tpval, 0);
|
rb_hook_list_connect_tracepoint(target, def->body.bmethod.hooks, tpval, 0);
|
||||||
rb_hash_aset(tp->local_target_set, target, Qfalse);
|
rb_hash_aset(tp->local_target_set, target, Qfalse);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user