VS2012: C++: Exception in multithreaded calls to setlocale - by camosMS

Status : 


Sign in
to vote
ID 794122 Comments
Status Active Workarounds
Type Bug Repros 2
Opened 7/16/2013 8:07:16 AM
Access Restriction Public


After converting my VC2005 solution to VC2012 the compiled executable crashes. I think the problem is located in setlocale. I created a brand new MFC executable in VS2012. I start three threads that do nothing except calling "setlocale (LC_NUMERIC, NULL);" After some seconds the example crashes. I also tried my example with VS2010 and VS2005: no crash in both. So the issue is new with VS2012

int giWorkerThreadCount = 3;


  while (true) {

    char *pLocale = setlocale (LC_NUMERIC, NULL); 
    if (pLocale && pLocale[0] != 'C')
      setlocale (LC_NUMERIC, "C");

    Sleep (100);

  return 1;

void CSetLocalyAppVC2005App::OnAppAbout()

  InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
  SetSecurityDescriptorDacl (&sd, TRUE, NULL, TRUE);
  sa.lpSecurityDescriptor = &sd;

  DWORD dwWorkerThreadID;
  for (int i = 0; i < giWorkerThreadCount; i++) {
    ::CreateThread (&sa, 0, fnHTTPGetThread, NULL, 0, &dwWorkerThreadID);
Sign in to post a comment.
Posted by a7FFEFF10 on 1/14/2017 at 11:58 AM
This is a very nasty issue. First, its reproducible when 2 or more threads _query_ locale via setlocale() and more viciously, if it doesn't crash, a recycled heap pointer can be corrupted.
Consider the following from setlocale.c (around line 90):
            if (ptloci->lc_category[_category].refcount != NULL &&
                InterlockedDecrement(ptloci->lc_category[_category].refcount) == 0) {

            if (!(ptd->_ownlocale & _PER_THREAD_LOCALE_BIT) &&
                        !(__globallocalestatus & _GLOBAL_LOCALE_BIT)) {
                if (ptloci->lc_category[_category].refcount != NULL &&
                    InterlockedDecrement(ptloci->lc_category[_category].refcount) == 0) {
If the refcount goes to zero and is freed by the first "if" block, then the decrement in the second "if" block is going to corrupt something; either the just-freed pointer, or some other thread's data if the pointer was unlucky enough to have acquired it.

Being the victim of a data-race (having a stale locale) is one thing. corrupting the heap is another. Please fix this and make an update available.
Posted by TolonUK on 3/16/2014 at 1:17 PM
Further to my previous comments, the program runs fine if I change the setlocale() call to _wsetlocale(). I tried the same in VS2010 and the situation is reversed.

That is:

For VS2012/13, simultaneous calls to setlocale(LC_NUMERIC, NULL) cause an AV, but simultaneous calls to _wsetlocale(LC_NUMERIC, NULL) are fine.
For VS2010, simultaneous calls to setlocale(LC_NUMBER, NULL) are fine, but simultaneous calls to _wsetlocale(LC_NUMERIC, NULL) cause an AV.

I've looked again at the code in setlocal.c and wsetloca.c and the difference appears to be because from VS2012 onwards, the setlocale functionality is implemented in the wide version of the function and the non-wide version delegates to it. The reverse is true for VS2010; the setlocale functionality is implemented in the non-wide version of the function and the wide version delegates to it.

This suggests to me that there ought to be a critical section covering the calling of the delegate function (e.g. _wsetlocale) and the reference-counted cleanup (in setlocale). This probably hasn't been spotted until now due to a _wsetlocale call being quite unlikely in a third-party C library (or at least, far less likely than setlocale).
Posted by TolonUK on 3/16/2014 at 8:50 AM
Forgot to mention - this works ok in VC prior to VS 2012. There appear to have been significant changes in the implementation of setlocale() introduced in that version (i.e. it now delegates to _wsetlocale()).
Posted by TolonUK on 3/16/2014 at 8:44 AM
This problem occurs even when just calling setlocale to get the current locale. The following program generates an access violation in the code that handles the cleanup of the MBCS copy of the current locale. Smells like a problem with reference counting, possibly due to the absence of a lock in setlocal.c between the call to _wsetlocale and the code processing the reference count. This is causing a problem with Windows/MSVC users of GDAL - see ticket https://trac.osgeo.org/gdal/ticket/5366

#include <locale.h>
#include <process.h>
#include <Windows.h>

void setlocale_loop(void*)
        setlocale(LC_NUMERIC, NULL);

int main()
    for (int i = 0; i < 2; i++)
        _beginthread(&setlocale_loop, 0, NULL);

    // Sleep the main thread
    Sleep(60 * 1000);
Posted by Microsoft on 7/25/2013 at 1:51 PM

As noted in my comments to the other bug (#790530), this is by-design. Unless you enable the per-thread locale, either by calling _configthreadlocale or by linking with the threadlocale.obj link option, calls to setlocale are not synchronized. Both the C and C++ Standard Library specifications state that the you must synchronize modification and use of the global locale.

Please feel free to contact me if you have any further questions.


James McNellis
Visual C++ Libraries
Posted by camosMS on 7/17/2013 at 1:29 AM
Seems that's the same as ID 790530. Can you explain, why my app needs to crashes now? Why you do not fix it in the CRT sources? I have tons of code created over years which may crash when build with new compiler. Is it true that I have to find the begin of each thread and call _configthreadlocale (_EPTL) there?
Posted by camosMS on 7/17/2013 at 12:52 AM
I created a new "Win32 console application" and added the code above. It crashed immediately. I added the zip to this ticket, but I cannot see it here. Please let me know if it's really not there. I will try upload again.
Posted by Microsoft on 7/16/2013 at 7:22 PM
Thank you for submitting feedback on Visual Studio and .NET Framework. In order to efficiently investigate and reproduce this issue, we are requesting additional information outlined below.

Could you please give us a demo project to demonstrate this issue so that we can conduct further research?

We look forward to hearing from you with this information.

Microsoft Visual Studio Connect Support Team
Posted by Microsoft on 7/16/2013 at 8:51 AM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)