Hi,

At Sat, 28 Feb 2009 15:47:18 +0900,
Brent Roman wrote in [ruby-core:22584]:
> First:
> The function evaluating a string literal node would, in some cases, pass the
> internal pointer of a newly created ruby string object into rb_reg_new(),
> which would derive a new regular expression object from it.  Trouble was,
> gcc, when optimizing on a machine like the x86-64, would determine that the
> pointer to the newly created string object need not be stacked and in fact
> could be entirely "forgotten" as soon its text buffer was passed into
> rb_reg_new().  Nothing wrong with that... unless a GC pass happened to be
> triggered while deriving the new regular expression from that string
> object's internal text buffer.  In which case, that now unreferenced String
> object would never be marked and, as a result, that String and its text
> buffer would be prematurely freed, trashing the regular expression pattern,
> resulting in very occasional regex match failures and (very rare) heap
> corruption.

Thank you, I consider you're correct, and merged into the 1.8
head.

> +       RB_GC_GUARD(str);  /* prevent tail call optimization here */

But I don't think tail call optimization could be here.
Possibly, it would be better to backport rb_reg_new_str() from
the trunk.

> Second:
(snip)
> I'm guessing that we are not seeing failures in the field because the x86-32
> has very few registers, so, in practice, variables are usually on the stack
> and thus preserved through longjmps even when they are not explicitly
> declared volatile.

I guess you misses a point here, gcc is aware of setjmp() and
emits code to save and restore registers into the stack before
and after it.  I suspect it doesn't work enough for some reason.
Anyway, your way would be correct for other compilers.

Should I split rb_eval() before your new patch, or do in
reverse order?

-- 
Nobu Nakada