Skip to content

Conversation

@peterzhu2118
Copy link
Contributor

I wrote the ruby_memcheck gem that wraps Valgrind's memcheck to check for memory leaks and bad memory accesses. This tool was able to find memory leaks #157 and #161.

Now, in addition to every test rake task, there's a test:valgrind task (e.g. test:unit:valgrind, test:integration:valgrind:lax, etc.)

I've also added a CI workflow that runs Valgrind.

To demonstrate the error messages, we can cherry-pick this PR over commit 90b0091. The error looks like the following:

Error messages

88 bytes in 1 blocks are definitely lost in loss record 19,187 of 29,837
  malloc (at /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  objspace_xmalloc0 (gc.c:10618)
  ruby_xmalloc0 (gc.c:10839)
  ruby_xmalloc_body (gc.c:10848)
  ruby_xmalloc (gc.c:12787)
 *vm_assembler_pool_alloc_assembler (vm_assembler_pool.c:59)
 *block_body_initialize (block.c:108)
  vm_call0_cfunc_with_frame (vm_eval.c:135)
  vm_call0_cfunc (vm_eval.c:149)
  vm_call0_body (vm_eval.c:180)
  vm_call0_cc (vm_eval.c:72)
  rb_call0 (vm_eval.c:505)
  rb_call (vm_eval.c:832)
  rb_funcallv_kw (vm_eval.c:1032)
  rb_class_new_instance_pass_kw (object.c:2110)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_call_method_each_type (vm_insnhelper.c:3416)
  vm_call_method (vm_insnhelper.c:3534)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:789)
  rb_vm_exec (vm.c:2163)
  vm_call0_body (vm_eval.c:176)
  vm_call0_cc (vm_eval.c:72)
  rb_call0 (vm_eval.c:505)
  rb_call (vm_eval.c:832)
  rb_funcallv_kw (vm_eval.c:1032)
  rb_class_new_instance_pass_kw (object.c:2110)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_call_method_each_type (vm_insnhelper.c:3416)
  vm_call_method (vm_insnhelper.c:3534)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:789)
  rb_vm_exec (vm.c:2163)
  invoke_block (vm.c:1263)
  invoke_iseq_block_from_c (vm.c:1335)
  invoke_block_from_c_bh (vm.c:1353)
  vm_yield (vm.c:1398)
  rb_yield_0 (vm_eval.c:1331)
  rb_yield (vm_eval.c:1347)
  rb_ary_each (array.c:2523)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:770)
  rb_vm_exec (vm.c:2163)
  invoke_block (vm.c:1263)
  invoke_iseq_block_from_c (vm.c:1335)
  invoke_block_from_c_bh (vm.c:1353)
  vm_yield (vm.c:1398)
  rb_yield_0 (vm_eval.c:1331)
  rb_yield (vm_eval.c:1347)
  rb_ary_collect (array.c:3635)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:770)
  rb_vm_exec (vm.c:2163)
  rb_vm_invoke_proc (vm.c:1485)
  rb_proc_call (proc.c:986)
  exec_end_procs_chain (eval_jump.c:105)
  rb_ec_exec_end_proc (eval_jump.c:120)
  rb_ec_teardown (eval.c:175)
  rb_ec_cleanup (eval.c:243)
  ruby_run_node (eval.c:375)
  main (main.c:50)

88 bytes in 1 blocks are definitely lost in loss record 19,188 of 29,837
  malloc (at /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  objspace_xmalloc0 (gc.c:10618)
  ruby_xmalloc0 (gc.c:10839)
  ruby_xmalloc_body (gc.c:10848)
  ruby_xmalloc (gc.c:12787)
 *vm_assembler_pool_alloc_assembler (vm_assembler_pool.c:59)
 *block_body_initialize (block.c:108)
  vm_call0_cfunc_with_frame (vm_eval.c:135)
  vm_call0_cfunc (vm_eval.c:149)
  vm_call0_body (vm_eval.c:180)
  vm_call0_cc (vm_eval.c:72)
  rb_call0 (vm_eval.c:505)
  rb_call (vm_eval.c:832)
  rb_funcallv_kw (vm_eval.c:1032)
  rb_class_new_instance_pass_kw (object.c:2110)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:789)
  rb_vm_exec (vm.c:2163)
  vm_call0_body (vm_eval.c:176)
  vm_call0_cc (vm_eval.c:72)
  rb_call0 (vm_eval.c:505)
  rb_call (vm_eval.c:832)
  rb_funcallv_kw (vm_eval.c:1032)
  rb_class_new_instance_pass_kw (object.c:2110)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:789)
  rb_vm_exec (vm.c:2163)
  vm_call0_body (vm_eval.c:176)
  vm_call0_cc (vm_eval.c:72)
  rb_funcallv_scope (vm_eval.c:1006)
  rb_funcallv (vm_eval.c:1026)
  rb_funcall (vm_eval.c:1097)
 *vm_render_until_error (vm.c:364)
  rb_vrescue2 (eval.c:1019)
  rb_rescue2 (eval.c:996)
 *liquid_vm_render (vm.c:550)
 *block_body_render_to_output_buffer (block.c:341)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:789)
  rb_vm_exec (vm.c:2163)
  invoke_block (vm.c:1263)
  invoke_iseq_block_from_c (vm.c:1335)
  invoke_block_from_c_bh (vm.c:1353)
  vm_yield (vm.c:1398)
  rb_yield_0 (vm_eval.c:1331)
  rb_yield (vm_eval.c:1347)
  rb_ary_each (array.c:2523)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:770)
  rb_vm_exec (vm.c:2163)
  invoke_block (vm.c:1263)
  invoke_iseq_block_from_c (vm.c:1335)
  invoke_block_from_c_bh (vm.c:1353)
  vm_yield (vm.c:1398)
  rb_yield_0 (vm_eval.c:1331)
  rb_yield (vm_eval.c:1347)
  rb_ary_collect (array.c:3635)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:770)
  rb_vm_exec (vm.c:2163)
  rb_vm_invoke_proc (vm.c:1485)
  rb_proc_call (proc.c:986)
  exec_end_procs_chain (eval_jump.c:105)
  rb_ec_exec_end_proc (eval_jump.c:120)
  rb_ec_teardown (eval.c:175)
  rb_ec_cleanup (eval.c:243)
  ruby_run_node (eval.c:375)
  main (main.c:50)

88 bytes in 1 blocks are definitely lost in loss record 19,189 of 29,837
  malloc (at /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  objspace_xmalloc0 (gc.c:10618)
  ruby_xmalloc0 (gc.c:10839)
  ruby_xmalloc_body (gc.c:10848)
  ruby_xmalloc (gc.c:12787)
 *vm_assembler_pool_alloc_assembler (vm_assembler_pool.c:59)
 *block_body_initialize (block.c:108)
  vm_call0_cfunc_with_frame (vm_eval.c:135)
  vm_call0_cfunc (vm_eval.c:149)
  vm_call0_body (vm_eval.c:180)
  vm_call0_cc (vm_eval.c:72)
  rb_call0 (vm_eval.c:505)
  rb_call (vm_eval.c:832)
  rb_funcallv_kw (vm_eval.c:1032)
  rb_class_new_instance_pass_kw (object.c:2110)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:789)
  rb_vm_exec (vm.c:2163)
  vm_call0_body (vm_eval.c:176)
  vm_call0_cc (vm_eval.c:72)
  rb_call0 (vm_eval.c:505)
  rb_call (vm_eval.c:832)
  rb_funcallv_kw (vm_eval.c:1032)
  rb_class_new_instance_pass_kw (object.c:2110)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:789)
  rb_vm_exec (vm.c:2163)
  vm_call0_body (vm_eval.c:176)
  vm_call0_cc (vm_eval.c:72)
  rb_funcallv_scope (vm_eval.c:1006)
  rb_funcallv (vm_eval.c:1026)
  rb_funcall (vm_eval.c:1097)
 *vm_render_until_error (vm.c:364)
  rb_vrescue2 (eval.c:1019)
  rb_rescue2 (eval.c:996)
 *liquid_vm_render (vm.c:550)
 *block_body_render_to_output_buffer (block.c:341)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:789)
  rb_vm_exec (vm.c:2163)
  vm_call0_body (vm_eval.c:176)
  vm_call0_cc (vm_eval.c:72)
  rb_funcallv_scope (vm_eval.c:1006)
  rb_funcallv (vm_eval.c:1026)
  rb_funcall (vm_eval.c:1097)
 *vm_render_until_error (vm.c:364)
  rb_vrescue2 (eval.c:1019)
  rb_rescue2 (eval.c:996)
 *liquid_vm_render (vm.c:550)
 *block_body_render_to_output_buffer (block.c:341)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:789)
  rb_vm_exec (vm.c:2163)
  invoke_block (vm.c:1263)
  invoke_iseq_block_from_c (vm.c:1335)
  invoke_block_from_c_bh (vm.c:1353)
  vm_yield (vm.c:1398)
  rb_yield_0 (vm_eval.c:1331)
  rb_yield (vm_eval.c:1347)
  rb_ary_each (array.c:2523)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:770)
  rb_vm_exec (vm.c:2163)
  invoke_block (vm.c:1263)
  invoke_iseq_block_from_c (vm.c:1335)
  invoke_block_from_c_bh (vm.c:1353)
  vm_yield (vm.c:1398)
  rb_yield_0 (vm_eval.c:1331)
  rb_yield (vm_eval.c:1347)
  rb_ary_collect (array.c:3635)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:770)
  rb_vm_exec (vm.c:2163)

400 bytes in 5 blocks are definitely lost in loss record 26,718 of 29,837
  calloc (at /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  calloc1 (gc.c:1583)
  objspace_xcalloc (gc.c:10871)
  ruby_xcalloc_body (gc.c:10878)
  ruby_xcalloc (gc.c:12807)
  rb_data_typed_object_zalloc (gc.c:2519)
 *expression_new (expression.c:37)
 *try_variable_strict_parse (variable.c:53)
  rb_vrescue2 (eval.c:1019)
  rb_rescue2 (eval.c:996)
 *internal_variable_compile_evaluate (variable.c:134)
 *internal_variable_compile (variable.c:141)
 *internal_block_body_parse (block.c:187)
 *block_body_parse (block.c:297)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:770)
  rb_vm_exec (vm.c:2163)
  invoke_block (vm.c:1263)
  invoke_iseq_block_from_c (vm.c:1335)
  invoke_block_from_c_bh (vm.c:1353)
  vm_yield (vm.c:1398)
  rb_yield_0 (vm_eval.c:1331)
  rb_yield (vm_eval.c:1347)
  rb_ary_each (array.c:2523)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:770)
  rb_vm_exec (vm.c:2163)
  invoke_block (vm.c:1263)
  invoke_iseq_block_from_c (vm.c:1335)
  invoke_block_from_c_bh (vm.c:1353)
  vm_yield (vm.c:1398)
  rb_yield_0 (vm_eval.c:1331)
  rb_yield (vm_eval.c:1347)
  rb_ary_collect (array.c:3635)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:770)
  rb_vm_exec (vm.c:2163)
  rb_vm_invoke_proc (vm.c:1485)
  rb_proc_call (proc.c:986)
  exec_end_procs_chain (eval_jump.c:105)
  rb_ec_exec_end_proc (eval_jump.c:120)
  rb_ec_teardown (eval.c:175)
  rb_ec_cleanup (eval.c:243)
  ruby_run_node (eval.c:375)
  main (main.c:50)

4,752 (4,664 direct, 88 indirect) bytes in 53 blocks are definitely lost in loss record 29,523 of 29,837
  malloc (at /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  objspace_xmalloc0 (gc.c:10618)
  ruby_xmalloc0 (gc.c:10839)
  ruby_xmalloc_body (gc.c:10848)
  ruby_xmalloc (gc.c:12787)
 *vm_assembler_pool_alloc_assembler (vm_assembler_pool.c:59)
 *block_body_initialize (block.c:108)
  vm_call0_cfunc_with_frame (vm_eval.c:135)
  vm_call0_cfunc (vm_eval.c:149)
  vm_call0_body (vm_eval.c:180)
  vm_call0_cc (vm_eval.c:72)
  rb_call0 (vm_eval.c:505)
  rb_call (vm_eval.c:832)
  rb_funcallv_kw (vm_eval.c:1032)
  rb_class_new_instance_pass_kw (object.c:2110)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:789)
  rb_vm_exec (vm.c:2163)
  vm_call0_body (vm_eval.c:176)
  vm_call0_cc (vm_eval.c:72)
  rb_call0 (vm_eval.c:505)
  rb_call (vm_eval.c:832)
  rb_funcallv_kw (vm_eval.c:1032)
  rb_class_new_instance_pass_kw (object.c:2110)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:789)
  rb_vm_exec (vm.c:2163)
  invoke_block (vm.c:1263)
  invoke_iseq_block_from_c (vm.c:1335)
  invoke_block_from_c_bh (vm.c:1353)
  vm_yield (vm.c:1398)
  rb_yield_0 (vm_eval.c:1331)
  rb_yield (vm_eval.c:1347)
  rb_ary_each (array.c:2523)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:770)
  rb_vm_exec (vm.c:2163)
  invoke_block (vm.c:1263)
  invoke_iseq_block_from_c (vm.c:1335)
  invoke_block_from_c_bh (vm.c:1353)
  vm_yield (vm.c:1398)
  rb_yield_0 (vm_eval.c:1331)
  rb_yield (vm_eval.c:1347)
  rb_ary_collect (array.c:3635)
  vm_call_cfunc_with_frame (vm_insnhelper.c:2926)
  vm_sendish (vm_insnhelper.c:4527)
  vm_exec_core (insns.def:770)
  rb_vm_exec (vm.c:2163)
  rb_vm_invoke_proc (vm.c:1485)
  rb_proc_call (proc.c:986)
  exec_end_procs_chain (eval_jump.c:105)
  rb_ec_exec_end_proc (eval_jump.c:120)
  rb_ec_teardown (eval.c:175)
  rb_ec_cleanup (eval.c:243)
  ruby_run_node (eval.c:375)
  main (main.c:50)

Add ruby_memcheck gem to find memory leaks in test suites. Test tasks
for liquid-c tests (unit and integration) are set up.
@peterzhu2118 peterzhu2118 merged commit d38956d into master Oct 20, 2021
@peterzhu2118 peterzhu2118 deleted the pz-ruby-memcheck branch October 20, 2021 18:05
@shopify-shipit shopify-shipit bot temporarily deployed to rubygems February 8, 2022 20:25 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants