Project

General

Profile

This project is closed and read-only.

Actions

Backport #11328

closed

Memory leak in str_buf_cat?

Backport #11328: Memory leak in str_buf_cat?

Added by skippy (adam greene) about 11 years ago. Updated about 11 years ago.

Status:
Closed
Assignee:
-

Description

There may be a memory leak in str_buf_cat that showed up in 2.2 but was 'fixed' in 2.3. The main reason I'm filing this issue is it looks like the 'fix' in 2.3 is actually a byproduct of another bug. So I wanted to file a ticket to bring this up and see about a test case to prevent a regression in the future.

Details:

all the usual caveats apply about a newbie to this issue tracker :) If you need additional information or a more formal writeup here rather than linking back to github, just ask.

thank you for your help!
Adam


Related issues 1 (0 open1 closed)

Is duplicate of Ruby - Bug #10942: Suspected memory leakClosedActions

Updated by jhaberman (Josh Haberman) about 11 years ago Actions #1

Hi, I am the maintainer of the Ruby Protobuf package.

To sum up the issue, we have a case where str_buf_cat() appears to leak memory in Ruby 2.2, but the following code (which seems like it should be equivalent) does not:

rb_str_modify_expand(rb_str, len);
char *p = RSTRING_PTR(rb_str);
memcpy(p + oldlen, str, len);
rb_str_set_len(rb_str, oldlen + len);

In other versions of Ruby, str_buf_cat() does not leak memory.

Updated by nagachika (Tomoyuki Chikanaga) about 11 years ago Actions #2

Hello, Adam and Josh.
First of all, thank you for your report.

Regards,

Updated by jhaberman (Josh Haberman) about 11 years ago Actions #3

Hi Tomoyuki, thank you for taking a look at this.

I was afraid this might be hard to reproduce in a reduced test case. I wasn't able to reproduce it with a pure Ruby program that just calls << over and over, even though that appears to use str_buf_cat() internally.

I was using Ruby from RVM. My ruby -v looks like:

ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-linux]

Here is the best way to reproduce the problem.

$ git clone https://github.com/google/protobuf.git
$ cd protobuf/ruby
$ ruby ext/google/protobuf_c/extconf.rb
$ make  (this will spew a lot of warnings, sorry)
$ cp protobuf_c.so lib/google/
$ export RUBYLIB=lib
$ ruby test.rb  (warning, this will allocate gigs of RAM)

Where test.rb is:

#!/usr/bin/ruby

require 'google/protobuf'
require 'pp'           
pool = Google::Protobuf::DescriptorPool.new
pool.build do
  add_message "M" do
    optional :foo, :string, 1
  end
end
M = pool.lookup("M").msgclass

# creates a ~50KB msg
m = M.new(:foo => ("hello" * 10_000))
data = M.encode(m)           
GC.start                     
puts "------------ pre run"
pp GC.stat
5_000_000.times do
  M.decode(data)
end
GC.start
puts "------------ post run"
pp GC.stat

Now edit ext/google/protobuf_c/encode_decode.c and replace rb_str_cat() on line 167 with this code, which seems like it should be equivalent:

size_t oldlen = RSTRING_LEN(rb_str);
rb_str_modify_expand(rb_str, len);
char *p = RSTRING_PTR(rb_str);
memcpy(p + oldlen, str, len);
rb_str_set_len(rb_str, oldlen + len);

Now the test no longer leaks memory.

You can also try the test with Ruby 2.1 (I tried ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-linux]) and the test does not leak memory.

Sorry I wasn't able to create a smaller test case.

Updated by nagachika (Tomoyuki Chikanaga) about 11 years ago Actions #4

  • Is duplicate of Bug #10942: Suspected memory leak added

Updated by nagachika (Tomoyuki Chikanaga) about 11 years ago Actions #5

  • Status changed from Open to Closed

Hi Josh, thank you for your information.

I can reproduce the leaks with 2.2.1(p85) and 2.2.2(p95). Thanks!
And I confirmed that this issue was already fixed on ruby_2_2 branch HEAD.
I've found that r50550 (https://github.com/ruby/ruby/commit/20ef4699e510f89ad4e9ccbeafa2d3d725ed2d3c) for #10942 fixes this issue too.
Coming 2.2.3 release include the fix. Please wait a while.

Updated by jhaberman (Josh Haberman) about 11 years ago Actions #6

Thanks Tomoyuki.

I will plan to modify my software to use the code above (with rb_str_modify_expand()) instead of rb_str_cat() -- does this seems like a reasonable approach?

Updated by skippy (adam greene) about 11 years ago Actions #7

Thank you both, and Tomoyuki, I appreciate the followup.

Actions

Also available in: PDF Atom