summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Zhu <[email protected]>2025-05-28 14:48:02 -0400
committerPeter Zhu <[email protected]>2025-05-29 16:06:49 -0400
commit9f91f3617bab2ee220d298ddb874ef73b10dac23 (patch)
treece7c20cebf483347d62159937bf6adf929441f8c
parent6a62a46c3cd8a0fe3623b5363ff21ead1e755169 (diff)
Fix memory leak with invalid yield in prism
[Bug #21383] The following script leaks memory: 10.times do 20_000.times do eval("class C; yield; end") rescue SyntaxError end puts `ps -o rss= -p #{$$}` end Before: 16464 25536 29424 35904 39552 44576 46736 51600 56096 59824 After: 13488 16160 18240 20528 19760 21808 21680 22272 22064 22336
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/13464
-rw-r--r--prism_compile.c1
-rw-r--r--test/ruby/test_ast.rb13
2 files changed, 14 insertions, 0 deletions
diff --git a/prism_compile.c b/prism_compile.c
index 63893c5184..c71c1429b2 100644
--- a/prism_compile.c
+++ b/prism_compile.c
@@ -1265,6 +1265,7 @@ pm_new_child_iseq(rb_iseq_t *iseq, pm_scope_node_t *node, VALUE name, const rb_i
type, ISEQ_COMPILE_DATA(iseq)->option, &error_state);
if (error_state) {
+ pm_scope_node_destroy(node);
RUBY_ASSERT(ret_iseq == NULL);
rb_jump_tag(error_state);
}
diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb
index 37b23e8db5..72a0d821a0 100644
--- a/test/ruby/test_ast.rb
+++ b/test/ruby/test_ast.rb
@@ -337,6 +337,19 @@ class TestAst < Test::Unit::TestCase
assert_parse("END {defined? yield}")
end
+ def test_invalid_yield_no_memory_leak
+ # [Bug #21383]
+ assert_no_memory_leak([], "#{<<-"begin;"}", "#{<<-'end;'}", rss: true)
+ code = proc do
+ eval("class C; yield; end")
+ rescue SyntaxError
+ end
+ 1_000.times(&code)
+ begin;
+ 100_000.times(&code)
+ end;
+ end
+
def test_node_id_for_location
omit if ParserSupport.prism_enabled?