diff options
| author | Peter Zhu <peter@peterzhu.ca> | 2024-11-08 14:33:48 -0500 |
|---|---|---|
| committer | Peter Zhu <peter@peterzhu.ca> | 2024-11-08 15:43:41 -0500 |
| commit | 51ffef281996727c60571771cd07c1459ba58cd2 (patch) | |
| tree | a6b6706cb5ed5324fadf271d49ecd0a336d9a53b /test/ruby | |
| parent | 72550d269ea89cd0bfcede7ad01a7c70ed01ba06 (diff) | |
Fix memory leak in prism when syntax error in iseq compilation
If there's a syntax error during iseq compilation then prism would leak
memory because it would not free the pm_parse_result_t.
This commit changes pm_iseq_new_with_opt to have a rb_protect to catch
when an error is raised, and return NULL and set error_state to a value
that can be raised by calling rb_jump_tag after memory has been freed.
For example:
10.times do
10_000.times do
eval("/[/=~s")
rescue SyntaxError
end
puts `ps -o rss= -p #{$$}`
end
Before:
39280
68736
99232
128864
158896
188208
217344
246304
275376
304592
After:
12192
13200
14256
14848
16000
16000
16000
16064
17232
17952
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/12036
Diffstat (limited to 'test/ruby')
| -rw-r--r-- | test/ruby/test_eval.rb | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/test/ruby/test_eval.rb b/test/ruby/test_eval.rb index cf1c2bb2f6..2129272b00 100644 --- a/test/ruby/test_eval.rb +++ b/test/ruby/test_eval.rb @@ -612,4 +612,28 @@ class TestEval < Test::Unit::TestCase x = orphan_lambda assert_equal(:ok, x.call) end + + def test_syntax_error_no_memory_leak + assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", rss: true) + begin; + 100_000.times do + eval("/[/=~s") + rescue SyntaxError + else + raise "Expected SyntaxError to be raised" + end + end; + + assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", rss: true) + begin; + a = 1 + + 100_000.times do + eval("if a in [0, 0] | [0, a]; end") + rescue SyntaxError + else + raise "Expected SyntaxError to be raised" + end + end; + end end |
