<div dir="ltr">The setlocale() thread-safeness problems are well known, but there is also a rather significant lack of a decent widely adopted workaround. This is the problem with many of the standard C libraries... they pre-date threading, and there was never consensus/standardizing on any thread safe alternative.<div>
<br></div><div>For any thread-safe alternative to work, everything needs to use it, but without a standard, you can pretty much guarantee that something you link will not use it, and some platforms won't even have it.</div>
<div><br></div><div>So instead, your best option is often to just declare your code non-thread-safe and recommend subprocesses instead... but then the inter-process communication libs are not as well developed as the threading libs.</div>
<div><br></div><div>Either that or completely embrace something like glib which replaces nearly everything in the standard C libs and only use other libs that also use glib. When you do this you also have to accept that your code doesn't look like normal C any more, and you might have some platform restrictions.</div>
<div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On 16 June 2014 08:39, Matthias Nagel <span dir="ltr"><<a href="mailto:matthias.h.nagel@gmail.com" target="_blank">matthias.h.nagel@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello,<br>
thanks. In the meantime I patched my Debian packages locally. But I ran into another race condition. rrd_update_r() isn't thread-save, because the C locale is an application wide variable. Assume one has rrdlib (A) and some other library (B) and the execution order is as follows:<br>
<br>
(A1) old_locale = setlocale(...)<br>
(B1) old_locale = setlocale(...)<br>
(A2) // do some locale-dependent stuff<br>
(A3) setlocale( old_locale )<br>
(B2) // do some locale-dependent stuff<br>
(B3) setlocale( old_locale )<br>
<br>
Here, library B can be any library that also sets the global C locale within a different thread context. In the best case some strings are misinterpreted, in the worst case the memory gets corrupted :-( At the moment, I wrote a work-around by using an application wide mutex that must be locked by any thread that wants to call any library that might change the global C locale. But of course this isn't very nice.<br>
<br>
Are there any chances that the rrd_update_r function (and relatives) will be rewritten? For example, C++ locales are bounded to a specific stream and are not global. At least there should be big, BIG warning at <a href="http://oss.oetiker.ch/rrdtool/prog/rrdthreads.en.html" target="_blank">http://oss.oetiker.ch/rrdtool/prog/rrdthreads.en.html</a> that the C locale is subject to a race condition.<br>
<br>
Regards, Matthias<br>
<br>
Am Sonntag, 15. Juni 2014, 22:37:01 schrieb Tobias Oetiker:<br>
<div class="HOEnZb"><div class="h5">> Hi Matthias,<br>
><br>
> yes you are right ... we fixed this in master, but not in the 1.4<br>
> branch ... it is now ...<br>
><br>
> cheers<br>
> tobi<br>
><br>
> Today Matthias Nagel wrote:<br>
><br>
> > Hello,<br>
> ><br>
> > I am writing a multi-threaded C++ application that uses rrdlib natively by calling rrd_update_r(). If I compile without optimazations and enable -ggdb everything seems to work fine. As soon as I switch to -O2 and disable -ggdb my apllication crashes at runtime.<br>
> ><br>
> > If it crashes the output is either<br>
> ><br>
> > *** glibc detected *** rrdtool: <something><br>
> ><br>
> > or<br>
> ><br>
> > expected timestamp not found in data source from <input><br>
> ><br>
> > but <input> is not the string that was given to rrd_update_r but unreadable garbage. Obviously, it is a memory corruption problem. Therefore, I ran the application under valgrind and I noticed that the problems comes from inside of the rrdlib. The message is<br>
> ><br>
> ><br>
> > ==11724== Invalid read of size 1<br>
> > ==11724== at 0x4C2A051: __GI_strcmp (mc_replace_strmem.c:712)<br>
> > ==11724== by 0x5A4FF7F: setlocale (setlocale.c:210)<br>
> > ==11724== by 0x505D06B: _rrd_update (rrd_update.c:982)<br>
> > ==11724== Address 0x9deb0d0 is 0 bytes inside a block of size 12 free'd<br>
> > ==11724== at 0x4C27D4E: free (vg_replace_malloc.c:427)<br>
> > ==11724== by 0x5A4FCBD: setname (setlocale.c:173)<br>
> > ==11724== by 0x5A500B0: setlocale (setlocale.c:417)<br>
> > ==11724== by 0x505D02D: _rrd_update (rrd_update.c:974)<br>
> ><br>
> > Let's have a look at it:<br>
> ><br>
> > rrd_update.c:973: old_locale = setlocale(LC_NUMERIC, NULL);<br>
> > rrd_update.c:974: setlocale(LC_NUMERIC, "C");<br>
> > rrd_update.c:982: setlocale(LC_NUMERIC, old_locale);<br>
> ><br>
> > The problem is obvious. The variable "old_locale" that is used at the 3rd line was assigned at the 1st line. But the 2nd call to "setlocale" freed the return value of the first call. According to the man pages the return value is a pointer to static memory and freed/allocated on every call. Actually the 2nd line (974) should be ommited and it should be<br>
> ><br>
> > rrd_update.c:973: old_locale = setlocale(LC_NUMERIC, "C" );<br>
> > rrd_update.c:974: // deleted<br>
> > rrd_update.c:982: setlocale(LC_NUMERIC, old_locale);<br>
> ><br>
> > Why this double call to "setlocale" anyway?<br>
> ><br>
> > Best regards, Matthias<br>
> ><br>
> ><br>
><br>
><br>
<br>
--<br>
</div></div><div class="im HOEnZb">Matthias Nagel<br>
Parkstraße 27<br>
76131 Karlsruhe<br>
<br>
Festnetz: <a href="tel:%2B49-721-96869289" value="+4972196869289">+49-721-96869289</a><br>
Mobil: <a href="tel:%2B49-151-15998774" value="+4915115998774">+49-151-15998774</a><br>
e-Mail: <a href="mailto:matthias.h.nagel@gmail.com">matthias.h.nagel@gmail.com</a><br>
ICQ: 499797758<br>
Skype: nagmat84<br>
<br>
</div><div class="HOEnZb"><div class="h5">_______________________________________________<br>
rrd-users mailing list<br>
<a href="mailto:rrd-users@lists.oetiker.ch">rrd-users@lists.oetiker.ch</a><br>
<a href="https://lists.oetiker.ch/cgi-bin/listinfo/rrd-users" target="_blank">https://lists.oetiker.ch/cgi-bin/listinfo/rrd-users</a><br>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>Donovan Baarda <<a href="mailto:abo@minkirri.apana.org.au">abo@minkirri.apana.org.au</a>>
</div>