ruby-rice / rice

Ruby Interface for C++ Extensions
http://ruby-rice.github.io/
Other
378 stars 63 forks source link

Fix for std::bad_alloc in MethodInfo #170

Closed ankane closed 2 years ago

ankane commented 2 years ago

Hi, I recently ran into a std::bad_alloc error when loading two gems that use Rice in the same script when one is precompiled (using rake-compiler-dock). The issue occurs on Linux but not Mac (haven't tried Windows).

Debugging with gdb led to this backtrace, which seems to point to the emplace_back call in MethodInfo.

#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff7aa3859 in __GI_abort () at abort.c:79
#2  0x00007ffff3e58911 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff3e6438c in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff3e643f7 in std::terminate() () from /lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffff3e646fd in __cxa_rethrow () from /lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007ffff3fbbe44 in std::vector<Rice::Arg, std::allocator<Rice::Arg> >::_M_realloc_insert<Rice::Arg&> (
    this=0x555555799eb8, __position=...) at /usr/include/c++/9/ext/new_allocator.h:119
#7  0x00007ffff3d86f7c in Rice::Arg& std::vector<Rice::Arg, std::allocator<Rice::Arg> >::emplace_back<Rice::Arg&>(Rice::Arg&) () from /var/lib/gems/2.7.0/gems/tomoto-0.3.0-x86_64-linux/lib/tomoto/tomoto.so
#8  0x00007ffff3d86345 in Rice::MethodInfo::MethodInfo<>(unsigned long) ()
   from /var/lib/gems/2.7.0/gems/tomoto-0.3.0-x86_64-linux/lib/tomoto/tomoto.so

There's no error when all functions defined in C++ have either no args or all the args are specified with Rice::Arg, which also points to that code path.

Changing MethodInfo to call addArg (which calls push_back) fixes the issue. However, I don't fully understand why, so wanted to see if it makes sense to you.

jasonroelofs commented 2 years ago

I'm not sure what emplace_back here is providing over the push_back that addArg calls, but this should be safe. @cfis do you remember why you chose emplace_back here?

cfis commented 2 years ago

I don't remember why I used emplace_back instead of push_back.

So feel free to change. However, I don't see how that is going to fix the bug mentioned above the way since the way the code is written either choice (push_back/emplace_back) should be the same. See https://quuxplusone.github.io/blog/2021/03/03/push-back-emplace-back/

ankane commented 2 years ago

Yeah, I didn't think they should be different either, but seems to make a difference in this specific case (but maybe there's something else going on).

ankane commented 2 years ago

Thanks @jasonroelofs!