Please understand that while Ruby giving you the crash report
saying [BUG] object allocation during garbage collection phase
is the proximate cause of the problem, I'm telling you that
the ultimate cause is likely a bug in the IBM gem. C extensions
have contracts they must uphold, and if they don't, they
crash the whole process. Ruby is the messenger in all crashes,
but it is incorrect to always blame the messenger. Crashes
involving threads like the one you are facing are by nature non-local;
the code initiating the crash is not always problematic.
about your guess that someone else is running Ruby code without holding the global VM lock, is not possible because in our Centos 8 server is the only application running and we have enough physical resources to run.
It is absolutely possible. The VM lock arbitrates
concurrency of threads within the same process. From the
stack trace, it's clear that you have multiple threads in your
Ruby process. The lock has nothing to do with how many
applications you run on your server. If you have multiple threads
in your Ruby process, it's in-play.
Here is something concrete you can try:
- Clone https://github.com/ibmdb/ruby-ibmdb to get the code for the version you're running.
5.4.0 seems to be at https://github.com/ibmdb/ruby-ibmdb/commit/2eec1bfe637e3320721daa5a92d3aa8001a00a5b
- Adjust the version,
gem build
and gem install
, then point your Gemfile
to that local version
- Make sure you can still reproduce the crash with this local version of the gem
- Apply the following patch (untested, you might have to fix build errors):
diff --git a/IBM_DB_Adapter/ibm_db/ext/ibm_db.c b/IBM_DB_Adapter/ibm_db/ext/ibm_db.c
index 200a527..0b139ee 100644
--- a/IBM_DB_Adapter/ibm_db/ext/ibm_db.c
+++ b/IBM_DB_Adapter/ibm_db/ext/ibm_db.c
@@ -686,6 +686,7 @@ static void _ruby_ibm_db_mark_stmt_struct(stmt_handle *handle)
static inline
VALUE ibm_Ruby_Thread_Call(rb_blocking_function_t *func, void *data1, rb_unblock_function_t *ubf, void *data2)
{
+ return func(data1);
void *(*f)(void*) = (void *(*)(void*))func;
return (VALUE)rb_thread_call_without_gvl(f, data1, ubf, data2);
}
- Repeat (2) to rebuild and reinstall the gem now that it's changed
- See if the crash still reproduces.
If this patch makes the crash go away, we can say with high confidence
that the ibm_db
gem is misusing rb_thread_call_without_gvl()
. Send this
to IBM as a bug report.
If the crash still happens, maybe you can try reproducing the bug without
any third-party C extensions. If you can do that, that'd be a more
actionable bug report for us. There is not much we can do on our end
with the information you have posted.