mudge/re2

Analyse Valgrind report

mudge opened this issue · 11 comments

mudge commented

Running ruby_memcheck has produced the following possible leaks from Valgrind:

16 bytes in 1 blocks are definitely lost in loss record 5,435 of 30,516
  operator new(unsigned long, std::nothrow_t const&) (vg_replace_malloc.c:592)
 *re2_regexp_scan(unsigned long, unsigned long) (re2.cc:1351)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:820)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  yield_under (vm_eval.c:1983)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2383)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  rb_ec_exec_node (eval.c:289)
  ruby_run_node (eval.c:330)
  rb_main (main.c:38)
  main (main.c:57)

32 bytes in 1 blocks are definitely lost in loss record 11,893 of 30,516
  operator new(unsigned long) (vg_replace_malloc.c:472)
 *re2::RE2::Init(std::basic_string_view<char, std::char_traits<char> >, re2::RE2::Options const&) (at /home/mudge/re2/lib/re2.so)
 *re2::RE2::RE2(char const*) (at /home/mudge/re2/lib/re2.so)
 *re2_GlobalReplace(unsigned long, unsigned long, unsigned long, unsigned long) (re2.cc:1439)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:820)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  yield_under (vm_eval.c:1983)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2383)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  rb_ec_exec_node (eval.c:289)
  ruby_run_node (eval.c:330)
  rb_main (main.c:38)
  main (main.c:57)

32 bytes in 1 blocks are definitely lost in loss record 11,894 of 30,516
  operator new(unsigned long) (vg_replace_malloc.c:472)
 *re2::RE2::Init(std::basic_string_view<char, std::char_traits<char> >, re2::RE2::Options const&) (at /home/mudge/re2/lib/re2.so)
 *re2::RE2::RE2(char const*) (at /home/mudge/re2/lib/re2.so)
 *re2_Replace(unsigned long, unsigned long, unsigned long, unsigned long) (re2.cc:1400)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:820)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  yield_under (vm_eval.c:1983)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2383)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  rb_ec_exec_node (eval.c:289)
  ruby_run_node (eval.c:330)
  rb_main (main.c:38)
  main (main.c:57)

32 bytes in 2 blocks are definitely lost in loss record 11,906 of 30,516
  operator new(unsigned long, std::nothrow_t const&) (vg_replace_malloc.c:592)
 *re2_regexp_scan(unsigned long, unsigned long) (re2.cc:1351)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:820)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  yield_under (vm_eval.c:1983)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  rb_vm_call0 (vm_eval.c:58)
  rb_vm_call_kw (vm_eval.c:303)
  vm_yield_with_cfunc (vm_insnhelper.c:4288)
  vm_invoke_ifunc_block (vm_insnhelper.c:4438)
  vm_invoke_block (vm_insnhelper.c:4493)
  vm_invokeblock_i (vm_insnhelper.c:5008)
  vm_sendish (vm_insnhelper.c:5088)
  vm_exec_core (insns.def:941)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  yield_under (vm_eval.c:1983)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2383)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  rb_ec_exec_node (eval.c:289)
  ruby_run_node (eval.c:330)
  rb_main (main.c:38)
  main (main.c:57)

40 bytes in 1 blocks are definitely lost in loss record 12,409 of 30,516
  operator new(unsigned long) (vg_replace_malloc.c:472)
 *re2::Regexp::ParseState::PushLiteral(int) (at /home/mudge/re2/lib/re2.so)
 *re2::Regexp::Parse(std::basic_string_view<char, std::char_traits<char> >, re2::Regexp::ParseFlags, re2::RegexpStatus*) (at /home/mudge/re2/lib/re2.so)
 *re2::RE2::Init(std::basic_string_view<char, std::char_traits<char> >, re2::RE2::Options const&) (at /home/mudge/re2/lib/re2.so)
 *re2::RE2::RE2(char const*) (at /home/mudge/re2/lib/re2.so)
 *re2_GlobalReplace(unsigned long, unsigned long, unsigned long, unsigned long) (re2.cc:1439)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:820)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  yield_under (vm_eval.c:1983)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2383)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  rb_ec_exec_node (eval.c:289)
  ruby_run_node (eval.c:330)
  rb_main (main.c:38)
  main (main.c:57)

71 bytes in 1 blocks are definitely lost in loss record 18,497 of 30,516
  operator new(unsigned long) (vg_replace_malloc.c:472)
  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long) (at /usr/lib/aarch64-linux-gnu/libstdc++.so.6.0.30)
  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_append(char const*, unsigned long) (at /usr/lib/aarch64-linux-gnu/libstdc++.so.6.0.30)
 *re2::RegexpStatus::Text[abi:cxx11]() const (at /home/mudge/re2/lib/re2.so)
 *re2::RE2::Set::Add(std::basic_string_view<char, std::char_traits<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) (at /home/mudge/re2/lib/re2.so)
 *re2_set_add(unsigned long, unsigned long) (re2.cc:1570)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:820)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  yield_under (vm_eval.c:1983)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2383)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  rb_ec_exec_node (eval.c:289)
  ruby_run_node (eval.c:330)
  rb_main (main.c:38)
  main (main.c:57)

72 (40 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 18,991 of 30,516
  operator new(unsigned long) (vg_replace_malloc.c:472)
 *re2::Regexp::ParseState::PushLiteral(int) (at /home/mudge/re2/lib/re2.so)
 *re2::Regexp::Parse(std::basic_string_view<char, std::char_traits<char> >, re2::Regexp::ParseFlags, re2::RegexpStatus*) (at /home/mudge/re2/lib/re2.so)
 *re2::RE2::Init(std::basic_string_view<char, std::char_traits<char> >, re2::RE2::Options const&) (at /home/mudge/re2/lib/re2.so)
 *re2::RE2::RE2(char const*) (at /home/mudge/re2/lib/re2.so)
 *re2_Replace(unsigned long, unsigned long, unsigned long, unsigned long) (re2.cc:1400)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:820)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  yield_under (vm_eval.c:1983)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2383)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  rb_ec_exec_node (eval.c:289)
  ruby_run_node (eval.c:330)
  rb_main (main.c:38)
  main (main.c:57)

152 bytes in 1 blocks are definitely lost in loss record 22,512 of 30,516
  operator new(unsigned long, std::nothrow_t const&) (vg_replace_malloc.c:592)
 *re2_regexp_initialize(int, unsigned long*, unsigned long) (re2.cc:796)
  vm_call0_cfunc_with_frame (vm_eval.c:150)
  vm_call0_cfunc (vm_eval.c:164)
  vm_call0_body (vm_eval.c:210)
  vm_call0_cc (vm_eval.c:87)
  rb_call0 (vm_eval.c:551)
  rb_class_new_instance_pass_kw (object.c:2021)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:820)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  yield_under (vm_eval.c:1983)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2383)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  rb_ec_exec_node (eval.c:289)
  ruby_run_node (eval.c:330)
  rb_main (main.c:38)
  main (main.c:57)

506 (432 direct, 74 indirect) bytes in 1 blocks are definitely lost in loss record 26,718 of 30,516
  operator new(unsigned long) (vg_replace_malloc.c:472)
 *re2::Compiler::Compiler() (at /home/mudge/re2/lib/re2.so)
 *re2::Compiler::Compile(re2::Regexp*, bool, long) (at /home/mudge/re2/lib/re2.so)
 *re2::Regexp::CompileToProg(long) (at /home/mudge/re2/lib/re2.so)
 *re2::RE2::Init(std::basic_string_view<char, std::char_traits<char> >, re2::RE2::Options const&) (at /home/mudge/re2/lib/re2.so)
 *re2::RE2::RE2(char const*) (at /home/mudge/re2/lib/re2.so)
 *re2_GlobalReplace(unsigned long, unsigned long, unsigned long, unsigned long) (re2.cc:1439)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:820)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  yield_under (vm_eval.c:1983)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2383)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  rb_ec_exec_node (eval.c:289)
  ruby_run_node (eval.c:330)
  rb_main (main.c:38)
  main (main.c:57)

528 (432 direct, 96 indirect) bytes in 1 blocks are definitely lost in loss record 27,033 of 30,516
  operator new(unsigned long) (vg_replace_malloc.c:472)
 *re2::Compiler::Compiler() (at /home/mudge/re2/lib/re2.so)
 *re2::Compiler::Compile(re2::Regexp*, bool, long) (at /home/mudge/re2/lib/re2.so)
 *re2::Regexp::CompileToProg(long) (at /home/mudge/re2/lib/re2.so)
 *re2::RE2::Init(std::basic_string_view<char, std::char_traits<char> >, re2::RE2::Options const&) (at /home/mudge/re2/lib/re2.so)
 *re2::RE2::RE2(char const*) (at /home/mudge/re2/lib/re2.so)
 *re2_Replace(unsigned long, unsigned long, unsigned long, unsigned long) (re2.cc:1400)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:820)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  yield_under (vm_eval.c:1983)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2383)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  invoke_block (vm.c:1398)
  invoke_iseq_block_from_c (vm.c:1454)
  invoke_block_from_c_bh (vm.c:1472)
  vm_yield_with_cref (vm.c:1509)
  vm_yield (vm.c:1517)
  rb_yield_0 (vm_eval.c:1348)
  rb_yield (vm_eval.c:1364)
  rb_ary_collect (array.c:3834)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3268)
  vm_sendish.constprop.0 (vm_insnhelper.c:5080)
  vm_exec_core (insns.def:801)
  rb_vm_exec (vm.c:2374)
  rb_ec_exec_node (eval.c:289)
  ruby_run_node (eval.c:330)
  rb_main (main.c:38)
  main (main.c:57)
stanhu commented

I remember doing this analysis a few months ago. I think the ones inre2::RE2::Init() are false positives. The first one was the most intriguing one, but I thought re2_scanner_free() should have handled that.

mudge commented

There’s a few involving StringPieces (now absl::string_views) which makes me wonder if there are some lifetime issues where the view is outliving the string or vice versa. I definitely want to take another look at how a Scanner contains a pointer to a StringPiece…

mudge commented

@peterzhu2118 suggested the source of the Scanner leak in rewind where I overwrite the input without deleting the old: https://ruby.social/@peterzhu2118/111108837791465609

stanhu commented

Oh, right, that makes sense.

mudge commented

Following @peterzhu2118's advice, I've been trying to focus on minimal test cases that trigger the Valgrind reports: for the leak in re2_regexp_initialize, it only occurs in the following example (all the other examples for that method return no leaks):

    it "raises an error if given an inappropriate type" do
      expect { RE2::Regexp.new(nil) }.to raise_error(TypeError)
    end
mudge commented

It seems to be fixed by adding a StringValue(pattern) earlier in the function before creating any RE2::Options or RE2 objects (presumably the previous calls to StringValuePtr were raising an exception after things had been allocated, causing them to never be freed).

mudge commented

This one has me currently stumped: re2_set_add leaks if and only if you hit this branch:

re2/ext/re2/re2.cc

Lines 1571 to 1573 in 23fab86

if (index < 0) {
rb_raise(rb_eArgError, "str rejected by RE2::Set->Add(): %s", err.c_str());
}

stanhu commented

My valgrind trace shows:

71 bytes in 1 blocks are definitely lost in loss record 18,062 of 30,701
  operator new(unsigned long) (at /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long) (at /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_append(char const*, unsigned long) (at /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
 *re2::RegexpStatus::Text[abi:cxx11]() const (regexp.cc:538)
 *re2::RE2::Set::Add(std::basic_string_view<char, std::char_traits<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) (set.cc:65)
 *re2_set_add(unsigned long, unsigned long) (re2.cc:1572)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3037)
  vm_call_method_each_type (vm_insnhelper.c:3639)
  vm_call_method (vm_insnhelper.c:3750)
  vm_sendish (vm_insnhelper.c:4751)
  vm_exec_core (insns.def:778)
  rb_vm_exec (vm.c:2211)
  invoke_block (vm.c:1316)
  invoke_iseq_block_from_c (vm.c:1372)
  invoke_block_from_c_bh (vm.c:1390)
  vm_yield_with_cref (vm.c:1427)
  yield_under (vm_eval.c:1969)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3037)
  vm_call_method_each_type (vm_insnhelper.c:3639)
  vm_call_method (vm_insnhelper.c:3750)
  vm_sendish (vm_insnhelper.c:4751)
  vm_exec_core (insns.def:759)
  rb_vm_exec (vm.c:2220)
  invoke_block (vm.c:1316)
  invoke_iseq_block_from_c (vm.c:1372)
  invoke_block_from_c_bh (vm.c:1390)
  vm_yield_with_cref (vm.c:1427)
  vm_yield (vm.c:1435)
  rb_yield_0 (vm_eval.c:1347)
  rb_yield (vm_eval.c:1363)
  rb_ary_collect (array.c:3564)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3037)
  vm_sendish (vm_insnhelper.c:4751)
  vm_exec_core (insns.def:759)
  rb_vm_exec (vm.c:2211)
  invoke_block (vm.c:1316)
  invoke_iseq_block_from_c (vm.c:1372)
  invoke_block_from_c_bh (vm.c:1390)
  vm_yield_with_cref (vm.c:1427)
  vm_yield (vm.c:1435)
  rb_yield_0 (vm_eval.c:1347)
  rb_yield (vm_eval.c:1363)
  rb_ary_collect (array.c:3564)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3037)
  vm_sendish (vm_insnhelper.c:4751)
  vm_exec_core (insns.def:759)
  rb_vm_exec (vm.c:2211)
  invoke_block (vm.c:1316)
  invoke_iseq_block_from_c (vm.c:1372)
  invoke_block_from_c_bh (vm.c:1390)
  vm_yield_with_cref (vm.c:1427)
  vm_yield (vm.c:1435)
  rb_yield_0 (vm_eval.c:1347)
  rb_yield (vm_eval.c:1363)
  rb_ary_collect (array.c:3564)
  vm_call_cfunc_with_frame (vm_insnhelper.c:3037)
  vm_sendish (vm_insnhelper.c:4751)
  vm_exec_core (insns.def:759)
  rb_vm_exec (vm.c:2211)
  rb_ec_exec_node (eval.c:280)
  ruby_run_node (eval.c:321)
  main (main.c:47)

Is valgrind flagging s.append(": "); in https://github.com/google/re2/blob/09de536bb7c77c2e0869a001f012d49560f56cbe/re2/regexp.cc#L538? This feels like a false positive.

I applied this diff to see the symbols in abseil and libre2:

diff --git a/ext/re2/extconf.rb b/ext/re2/extconf.rb
index f8fd706..c8c6681 100644
--- a/ext/re2/extconf.rb
+++ b/ext/re2/extconf.rb
@@ -119,8 +119,8 @@ end

 def build_extension(static_p = false)
   # Enable optional warnings but disable deprecated register warning for Ruby 2.6 support
-  $CFLAGS << " -Wall -Wextra -funroll-loops"
-  $CPPFLAGS << " -Wno-register"
+  $CFLAGS << " -Wall -Wextra -funroll-loops -ggdb3"
+  $CPPFLAGS << " -Wno-register -ggdb3"

   # Pass -x c++ to force gcc to compile the test program
   # as C++ (as it will end in .c by default).
@@ -395,11 +395,11 @@ def build_with_vendored_libraries
   abseil_recipe, re2_recipe = load_recipes

   process_recipe(abseil_recipe) do |recipe|
-    recipe.configure_options += ['-DABSL_PROPAGATE_CXX_STD=ON', '-DCMAKE_CXX_VISIBILITY_PRESET=hidden']
+    recipe.configure_options += ['-DABSL_PROPAGATE_CXX_STD=ON', '-DCMAKE_CXX_VISIBILITY_PRESET=hidden', '-DCMAKE_CXXFLAGS=-ggdb3']
   end

   process_recipe(re2_recipe) do |recipe|
-    recipe.configure_options += ["-DCMAKE_PREFIX_PATH=#{abseil_recipe.path}", '-DCMAKE_CXX_FLAGS=-DNDEBUG',
+    recipe.configure_options += ["-DCMAKE_PREFIX_PATH=#{abseil_recipe.path}", '-DCMAKE_CXX_FLAGS=-DNDEBUG', '-DCMAKE_CXX_FLAGS=-ggdb3',
                                  '-DCMAKE_CXX_VISIBILITY_PRESET=hidden']
   end
mudge commented

I've been talking to Peter on ruby.social about this while I look into it: https://ruby.social/@mudge/111110365227989022

In short, the leak disappears if I remove the err string and stop passing it to Add() but that doesn't seem right.

stanhu commented

As https://valgrind.org/docs/manual/faq.html#faq.reports mentions:

Many implementations of the C++ standard libraries use their own memory pool allocators. Memory for quite a number of destructed objects is not immediately freed and given back to the OS, but kept in the pool(s) for later re-use. The fact that the pools are not freed at the exit of the program cause Valgrind to report this memory as still reachable. The behaviour not to free pools at the exit could be called a bug of the library though.

I tried to make valgrind run with GLIBCXX_FORCE_NEW yet, but so far that hasn't helped.

mudge commented

I think I've now fixed all the leaks in this report in #105