Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test with Valgrind using the ruby_memcheck gem #162

Merged
merged 3 commits into from
Oct 20, 2021
Merged

Conversation

peterzhu2118
Copy link
Member

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