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