diff options
author | Eric Wong <normalperson@yhbt.net> | 2010-02-13 01:35:55 -0800 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2010-02-13 01:35:55 -0800 |
commit | 4247fafd0f361d2373df7213a1a0028554e93d93 (patch) | |
tree | e4e8e3f52b909725264463993422779892e3cdd4 /test/test_clogger.rb | |
parent | 883368f745af13a57b3784b834001a82823eee05 (diff) | |
download | clogger-4247fafd0f361d2373df7213a1a0028554e93d93.tar.gz |
The optional C extension leaked memory due to improper use of the Ruby API, causing duplicated objects to never be garbage collected. I misread the Data_Make_Struct/Data_Wrap_Struct documentation and ended up passing NULL as the "free" argument instead of -1, causing the memory to never be freed. From README.EXT in the MRI source which I misread: > The free argument is the function to free the pointer > allocation. If this is -1, the pointer will be just freed. > The functions mark and free will be called from garbage > collector.
Diffstat (limited to 'test/test_clogger.rb')
-rw-r--r-- | test/test_clogger.rb | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/test/test_clogger.rb b/test/test_clogger.rb index b086bbb..4dab3fc 100644 --- a/test/test_clogger.rb +++ b/test/test_clogger.rb @@ -587,4 +587,22 @@ class TestClogger < Test::Unit::TestCase assert ! cl.reentrant? end + # so we don't care about the portability of this test + # if it doesn't leak on Linux, it won't leak anywhere else + # unless your C compiler or platform is otherwise broken + LINUX_PROC_PID_STATUS = "/proc/self/status" + def test_memory_leak + app = lambda { |env| [ 0, {}, [] ] } + clogger = Clogger.new(app, :logger => $stderr) + match_rss = /^VmRSS:\s+(\d+)/ + if File.read(LINUX_PROC_PID_STATUS) =~ match_rss + before = $1.to_i + 1000000.times { clogger.dup } + File.read(LINUX_PROC_PID_STATUS) =~ match_rss + after = $1.to_i + diff = after - before + assert(diff < 10000, "memory grew more than 10M: #{diff}") + end + end if RUBY_PLATFORM =~ /linux/ && test(?r, LINUX_PROC_PID_STATUS) + end |