
On 1/12/2012 6:29 AM, Ovanes Markarian wrote:
Hello *,
I prefer Eric, but hey. ;-)
I face some issue with sporadic crashes in xpressive which I think a result of a race condition. The use case is:
a function which needs to parse smth create local regex objects:
const sregex any_char = _; sregex const& rdelim = parser_->delimiter(); //some dynamic delimiter token
I'm going to guess that parser_->delimiter() returns an sregex object that is either global or held within parser_, is that right?
const sregex re_prefix = bos >> (s1=-*by_ref(any_char)) >> *(s2=by_ref(rdelim)) >> eos ;
calling this function from multiple threads results in a crash with (boost 1.42, gcc 4.3.5 on debian linux). I previously had more crashes, but moved all regex objects to global space as const objects and they seem to be fine now. This is the only place I left with a local regex.
In the stack trace it seems like internals of the local object regex are freed via boost weak_ptr with possible double delete attempt.
Yep, I know the problem. I'm sorry to say that it's by design -- or rather, that it's a known limitation of the way regex impls are ref-counted and would be very hard to fix, if it can be fixed at all. At least it's documented, but you'd have to read the docs very carefully. See here: http://www.boost.org/doc/libs/1_48_0/doc/html/xpressive/user_s_guide.html#bo... You're nesting regex objects; i.e., building a grammar. When you are building a grammar, both the outer *and* inner regex objects are modified. What is happening is that the sregex object (presumably) held by parser_ is being mutated simultaneously from several threads. That's bad. That link tells you that you need to build your grammars on a single thread. I would create this regex once the same place where you build the regex returned by parser_->delimiter(). Then use that regex instead of constructing it at local scope over and over. HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com