Multi-threaded C++, new, and xmalloc


I have a C++ application with an embedded ruby interpreter. I have
overridden the new() operator globally:

void* operator new (size_t size)
void *p=xmalloc(size);
if (p==0) // did malloc succeed?
throw std::bad_alloc(); // ANSI/ISO compliant behavior
return p;

void operator delete (void *p)

This keeps the GC informed about allocations. It has been working
wonderfully for months but just recently the program has been crashing
badly. I’ve narrowed it down to allocations on some worker threads on
the C++ side. While they do not interact with ruby directly, any
allocations will obviously be routed through xmalloc, and hence might
cause memory corruption.

Does anybody have a clue how to fix this?


I suppose the obvious answer is to synchronise access to the xmalloc
function… or to mash the worker threads into the main thread via my
message pump. I’ll try the former.

Tim Hollingsworth wrote:

I suppose the obvious answer is to synchronise access to the xmalloc

ok so that didn’t work. To go down that road would probably require
synchronising all access to the ruby interpreter.

I’m sure you know this, but just in case: the embedded Ruby interpreter
does not work well with a multi-threaded application because it has
global variables and therefore cannot be re-entrant.

“ruby is not thread-safe. If you embed ruby into a multi-threaded
application then you will need to semaphore protect all access to ruby.
Warning: Insufficient semaphore protection can be hard debuggable.” -

You would have to somehow organize a separate instance of each Ruby
interpreter on a per-thread basis, or have a locking decorator that
intercepts all calls to Ruby using a mutex. Or something like that. I
believe that Ruby 2 is aiming to overcome the lack of re-entrancy. I
wonder when Ruby 2’s day will be (sorry, Mick; cringes, ducks and runs).

On Thu, Nov 23, 2006 at 08:38:30PM +0900, Tim Hollingsworth wrote:

This keeps the GC informed about allocations.

I think this is probably unnecessary. You’re informing the GC about
allocations for memory it doesn’t control. The GC may be invoked more
often, but it won’t be able to free any more memory. If you don’t use
xmalloc, then the GC should still function correctly, and will still
try to free memory if malloc fails (though I suppose it’s a little
unfortunate that malloc doesn’t typically fail on many operating