From: "Iñaki Baz Castillo" Date: 2012-06-12T01:35:32+09:00 Subject: [C ext] segmentfault in vfprintf() when using fprintf() from a Ruby thread without GVL Hi, I've added a TRACE C macro to my C functions. Some of those functions runs without the GVL (Ruby 1.9.3), for example the ubf() unblocking function passed to rb_thread_call_without_gvl(), which could be called without the GVL or without it. Other functions also are executed without the GVL and wihint them they call to my TRACE macro. The macro si simple: --------------------------- #define TRACE fprintf(stderr, "TRACE: %s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__) ---------------------------- When I enable such a macro and lot of messages are written to stderr, sometimes I get a segmentfault. gdb shows this: (gdb) bt #0 0x00007fb8c11f3f6f in ?? () from /lib/x86_64-linux-gnu/libc.so.6 #1 0x00007fb8c11eec1e in vfprintf () from /lib/x86_64-linux-gnu/libc.so.6 #2 0x00007fb8c11f9607 in fprintf () from /lib/x86_64-linux-gnu/libc.so.6 #3 0x00007fb8bf899ec4 in my_ubf () from /home/ibc/projects/xxxxxxx/lib/xxxxxxx/xxxxxxx_ext.so #4 0x00007fb8c16bca8d in ?? () from /usr/lib/libruby-1.9.1.so.1.9 #5 0x00007fb8c16bdfcf in ?? () from /usr/lib/libruby-1.9.1.so.1.9 #6 0x00007fb8c0f91e9a in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0 #7 0x00007fb8c12994bd in clone () from /lib/x86_64-linux-gnu/libc.so.6 In theory vfprintf() is thread-safe: http://www.mkssoftware.com/docs/man3/printf.3.asp ---------------------- MULTITHREAD SAFETY LEVEL fprintf(), printf(), snprintf(), sprintf(): MT-Safe, with exceptions. vfprintf(), vprintf(), vsnprintf(), vsprintf(): MT-Safe, with exceptions. These functions are MT-Safe as long as no thread calls setlocale() while these functions are executing. ---------------------- I don't call to setlocale() in my C extension. Looking into Ruby 1.9.3-p125 it calls setlocal() in main.c: -------------------------- int main(int argc, char **argv) { #ifdef RUBY_DEBUG_ENV ruby_set_debug_option(getenv("RUBY_DEBUG")); #endif #ifdef HAVE_LOCALE_H setlocale(LC_CTYPE, ""); #endif ------------------------- The fact is that I can just reproduce the segmentfault with "rake test", which executes some test units (require "test/unit"). Maybe TestUnit or rake does something "strange"? Thanks a lot. -- Iñaki Baz Castillo