From 97daf35addf51951748d2954580fe10dffd3be36 Mon Sep 17 00:00:00 2001 From: Zhuochun Date: Sun, 13 Mar 2016 16:19:56 +0800 Subject: Fix Ruby memory leaks - `recv_message` is not cleaned up after call - `send_message` is not cleaned up in failure cases - `xmalloc` ruby string is not freed after used --- src/ruby/ext/grpc/rb_byte_buffer.c | 7 +++++-- src/ruby/ext/grpc/rb_call.c | 14 +++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ruby/ext/grpc/rb_byte_buffer.c b/src/ruby/ext/grpc/rb_byte_buffer.c index db7cac363a..52523b8319 100644 --- a/src/ruby/ext/grpc/rb_byte_buffer.c +++ b/src/ruby/ext/grpc/rb_byte_buffer.c @@ -52,12 +52,12 @@ grpc_byte_buffer* grpc_rb_s_to_byte_buffer(char *string, size_t length) { VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) { size_t length = 0; char *string = NULL; + VALUE rb_string; size_t offset = 0; grpc_byte_buffer_reader reader; gpr_slice next; if (buffer == NULL) { return Qnil; - } length = grpc_byte_buffer_length(buffer); string = xmalloc(length + 1); @@ -65,6 +65,9 @@ VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) { while (grpc_byte_buffer_reader_next(&reader, &next) != 0) { memcpy(string + offset, GPR_SLICE_START_PTR(next), GPR_SLICE_LENGTH(next)); offset += GPR_SLICE_LENGTH(next); + gpr_slice_unref(next); } - return rb_str_new(string, length); + rb_string = rb_str_new(string, length); + xfree(string); + return rb_string; } diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c index cd0aa6aaf2..b0829efdc7 100644 --- a/src/ruby/ext/grpc/rb_call.c +++ b/src/ruby/ext/grpc/rb_call.c @@ -551,13 +551,26 @@ static void grpc_run_batch_stack_init(run_batch_stack *st, /* grpc_run_batch_stack_cleanup ensures the run_batch_stack is properly * cleaned up */ static void grpc_run_batch_stack_cleanup(run_batch_stack *st) { + size_t i = 0; + grpc_metadata_array_destroy(&st->send_metadata); grpc_metadata_array_destroy(&st->send_trailing_metadata); grpc_metadata_array_destroy(&st->recv_metadata); grpc_metadata_array_destroy(&st->recv_trailing_metadata); + if (st->recv_status_details != NULL) { gpr_free(st->recv_status_details); } + + if (st->recv_message != NULL) { + grpc_byte_buffer_destroy(st->recv_message); + } + + for (i = 0; i < st->op_num; i++) { + if (st->ops[i].op == GRPC_OP_SEND_MESSAGE) { + grpc_byte_buffer_destroy(st->ops[i].data.send_message); + } + } } /* grpc_run_batch_stack_fill_ops fills the run_batch_stack ops array from @@ -643,7 +656,6 @@ static VALUE grpc_run_batch_stack_build_result(run_batch_stack *st) { break; case GRPC_OP_SEND_MESSAGE: rb_struct_aset(result, sym_send_message, Qtrue); - grpc_byte_buffer_destroy(st->ops[i].data.send_message); break; case GRPC_OP_SEND_CLOSE_FROM_CLIENT: rb_struct_aset(result, sym_send_close, Qtrue); -- cgit v1.2.3