Boost logo

Boost Users :

Subject: Re: [Boost-users] [xpressive] sporadic crashes in multi-threaded code
From: Eric Niebler (eric_at_[hidden])
Date: 2012-01-13 23:35:07


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#boost_xpressive.user_s_guide.tips_n_tricks.create_grammars_on_a_single_thread

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

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net