<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&#39;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&#39;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">&lt;<a href="mailto:matthias.h.nagel@gmail.com" target="_blank">matthias.h.nagel@gmail.com</a>&gt;</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&#39;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&#39;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">&gt; Hi Matthias,<br>
&gt;<br>
&gt; yes you are right ... we fixed this in master, but not in the 1.4<br>
&gt; branch ... it is now ...<br>
&gt;<br>
&gt; cheers<br>
&gt; tobi<br>
&gt;<br>
&gt; Today Matthias Nagel wrote:<br>
&gt;<br>
&gt; &gt; Hello,<br>
&gt; &gt;<br>
&gt; &gt; 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>

&gt; &gt;<br>
&gt; &gt; If it crashes the output is either<br>
&gt; &gt;<br>
&gt; &gt; *** glibc detected *** rrdtool: &lt;something&gt;<br>
&gt; &gt;<br>
&gt; &gt; or<br>
&gt; &gt;<br>
&gt; &gt; expected timestamp not found in data source from &lt;input&gt;<br>
&gt; &gt;<br>
&gt; &gt; but &lt;input&gt; 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>

&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; ==11724== Invalid read of size 1<br>
&gt; &gt; ==11724==    at 0x4C2A051: __GI_strcmp (mc_replace_strmem.c:712)<br>
&gt; &gt; ==11724==    by 0x5A4FF7F: setlocale (setlocale.c:210)<br>
&gt; &gt; ==11724==    by 0x505D06B: _rrd_update (rrd_update.c:982)<br>
&gt; &gt; ==11724==  Address 0x9deb0d0 is 0 bytes inside a block of size 12 free&#39;d<br>
&gt; &gt; ==11724==    at 0x4C27D4E: free (vg_replace_malloc.c:427)<br>
&gt; &gt; ==11724==    by 0x5A4FCBD: setname (setlocale.c:173)<br>
&gt; &gt; ==11724==    by 0x5A500B0: setlocale (setlocale.c:417)<br>
&gt; &gt; ==11724==    by 0x505D02D: _rrd_update (rrd_update.c:974)<br>
&gt; &gt;<br>
&gt; &gt; Let&#39;s have a look at it:<br>
&gt; &gt;<br>
&gt; &gt; rrd_update.c:973: old_locale = setlocale(LC_NUMERIC, NULL);<br>
&gt; &gt; rrd_update.c:974: setlocale(LC_NUMERIC, &quot;C&quot;);<br>
&gt; &gt; rrd_update.c:982: setlocale(LC_NUMERIC, old_locale);<br>
&gt; &gt;<br>
&gt; &gt; The problem is obvious. The variable &quot;old_locale&quot; that is used at the 3rd line was assigned at the 1st line. But the 2nd call to &quot;setlocale&quot; 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>

&gt; &gt;<br>
&gt; &gt; rrd_update.c:973: old_locale = setlocale(LC_NUMERIC, &quot;C&quot; );<br>
&gt; &gt; rrd_update.c:974: // deleted<br>
&gt; &gt; rrd_update.c:982: setlocale(LC_NUMERIC, old_locale);<br>
&gt; &gt;<br>
&gt; &gt; Why this double call to &quot;setlocale&quot; anyway?<br>
&gt; &gt;<br>
&gt; &gt; Best regards, Matthias<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt;<br>
&gt;<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 &lt;<a href="mailto:abo@minkirri.apana.org.au">abo@minkirri.apana.org.au</a>&gt;
</div>