为什么在使用 MinGW 添加 ltalloc 时会出现分段错误

Why do I get a segmentation fault when adding ltalloc with MinGW

我尝试使用 ltalloc 构建我的应用程序。我用 MinGW32 4.9.1 和 MinGW64-32 4.9.2 试过了。 它可以很好地编译和链接,但是当我 运行 它发生分段错误时。调试将问题定位到以下代码:

#include <pthread.h>
#pragma weak pthread_once
#pragma weak pthread_key_create
#pragma weak pthread_setspecific
static pthread_key_t pthread_key;
static pthread_once_t init_once = PTHREAD_ONCE_INIT;
static void init_pthread_key() { pthread_key_create(&pthread_key, release_thread_cache); }
static thread_local int thread_initialized = 0;
static void init_pthread_destructor()//must be called only when some block placed into a thread cache's free list
{
    if (unlikely(!thread_initialized))
    {
        thread_initialized = 1;
        if (pthread_once)
        {
            pthread_once(&init_once, init_pthread_key);  // <--- THIS CAUSES THE SEGSEGV
            pthread_setspecific(pthread_key, (void*)1);//set nonzero value to force calling of release_thread_cache() on thread terminate
        }
    }
}

据我所知,这两个版本本身都支持线程本地存储。 ltalloc的wiki也写了以下内容:

Warning: in some builds of MinGW there is a problem with emutls and order of execution of thread destructor (all thread local variables destructed before it), and termination of any thread will lead to application crash.

不幸的是,这个警告没有告诉我任何信息。谷歌搜索也没有让我变得更聪明。

出乎意料,试试这个:

static void init_pthread_key(void) 
{ 
  if (pthread_key_create)
  {
    pthread_key_create(&pthread_key, release_thread_cache); 
  }
}

同时向 pthread_* 添加完整的错误检查可能不仅有助于调试。