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.