为什么在使用 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_*
添加完整的错误检查可能不仅有助于调试。
我尝试使用 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_*
添加完整的错误检查可能不仅有助于调试。