pthread_join 在 OSX 上因分段错误而间歇性崩溃

发布于 2024-12-08 18:59:03 字数 2484 浏览 0 评论 0原文

我在加入子线程时遇到分段错误,并且我已经用尽了所有我能想到的调试选项,查看堆栈溢出和互联网的其余部分! :) 我会的 尽我所能。该代码是用 C++ 编写的,并在 OSX 10.6.8 上使用 GNU GCC 编译。我已使用“-pthread”参数链接到“pthread”库。我也尝试过“-lphtread”。没有区别。

我正在使用以下全局变量:

pthread_t gTid;

pthread_attr_t gAttr;

int gExitThread = 0;

我正在从我的主执行线程创建一个子线程:

err = pthread_attr_init(&gAttr);
if (err)
{
    throw CONTROLLER_THREAD_ERROR;
}

err = pthread_attr_setdetachstate(&gAttr, PTHREAD_CREATE_JOINABLE);
if (err)
{
    throw CONTROLLER_THREAD_ERROR;
}

err = pthread_create(&gTid,&gAttr,threadHandler,NULL);
if (err)
{
    throw CONTROLLER_THREAD_ERROR;
}

在“threadHandler”内部,我使用核心基础 API 有以下运行循环:

// Enter run loop
result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, RUN_LOOP_TIMEOUT, false);
while (result == kCFRunLoopRunTimedOut)
{
    if (gExitThread) break;
    result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, RUN_LOOP_TIMEOUT, false);
}

gExitThread 全局变量用于表示线程应该优雅地杀死 本身。 RUN_LOOP_TIMEOUT 宏设置为 2 秒(尽管较大和较小的值没有区别)。

主线程中的以下代码片段通知线程将被终止:

int err = 0;
void* exitValue = NULL;

printf("Stopping controller thread...\n");

gExitThread = 1;
err = pthread_join(gTid, &exitValue);
if (err)
{
    displayError2(err);
    throw CONTROLLER_THREAD_ERROR;
}

err = pthread_attr_destroy(&gAttr);
if (err)
{
    throw CONTROLLER_THREAD_ERROR;
}

短暂延迟后,对“pthread_join”的调用因分段错误而崩溃。我还注意到,将“pthread_join”的调用替换为正常的睡眠(比如说两秒),会在执行“usleep(2000000)”时导致完全相同的分段错误! 我将复制下面“pthread_join”和“usleep”的核心转储的反向跟踪。

pthread_join:

#0  0x00007fff8343aa6a in __semwait_signal ()
#1  0x00007fff83461896 in pthread_join ()
#2  0x000000010000179d in Controller::cleanup () at src/native/osx/controllers.cpp:335
#3  0x0000000100008e51 in ControllersTest::performTest (this=0x100211bf0) at unittests/src/controllers_test.cpp:70
#4  0x000000010000e5b9 in main (argc=2, argv=0x7fff5fbff980) at unittests/src/verify.cpp:34

usleep(2000000):

#0  0x00007fff8343aa6a in __semwait_signal ()
#1  0x00007fff8343a8f9 in nanosleep ()
#2  0x00007fff8343a863 in usleep ()
#3  0x000000010000177b in Controller::cleanup () at src/native/osx/controllers.cpp:335
#4  0x0000000100008e3d in ControllersTest::performTest (this=0x100211bf0) at unittests/src/controllers_test.cpp:70
#5  0x000000010000e5a5 in main (argc=2, argv=0x7fff5fbff980) at unittests/src/verify.cpp:34

任何帮助将不胜感激。

I'm getting a segmentation fault while joining on a child thread and I've exhausted all options I could think of debugging, looking on Stack-overflow and the rest of the Internet! :) I'll be
as thorough as I can. The code is written in C++ and compiled with GNU GCC on OSX 10.6.8. I've linked in the 'pthread' library using the '-pthread' parameter. I've also tried '-lphtread'. No difference.

I'm using the following global variables:

pthread_t gTid;

pthread_attr_t gAttr;

int gExitThread = 0;

I'm creating a child thread from my main thread of execution:

err = pthread_attr_init(&gAttr);
if (err)
{
    throw CONTROLLER_THREAD_ERROR;
}

err = pthread_attr_setdetachstate(&gAttr, PTHREAD_CREATE_JOINABLE);
if (err)
{
    throw CONTROLLER_THREAD_ERROR;
}

err = pthread_create(&gTid,&gAttr,threadHandler,NULL);
if (err)
{
    throw CONTROLLER_THREAD_ERROR;
}

Inside 'threadHandler', I have the following run loop using the core foundation API:

// Enter run loop
result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, RUN_LOOP_TIMEOUT, false);
while (result == kCFRunLoopRunTimedOut)
{
    if (gExitThread) break;
    result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, RUN_LOOP_TIMEOUT, false);
}

The gExitThread global variable is used to signal that the thread should gracefully kill
itself. The RUN_LOOP_TIMEOUT macro is set to 2 seconds (although larger and smaller values make no difference).

The thread is signalled to be killed by the following piece of code in the main thread:

int err = 0;
void* exitValue = NULL;

printf("Stopping controller thread...\n");

gExitThread = 1;
err = pthread_join(gTid, &exitValue);
if (err)
{
    displayError2(err);
    throw CONTROLLER_THREAD_ERROR;
}

err = pthread_attr_destroy(&gAttr);
if (err)
{
    throw CONTROLLER_THREAD_ERROR;
}

The call to 'pthread_join' crashes with a segmentation fault after a short delay. I've also noticed that replacing the call of 'pthread_join' with a normal sleep of let's say two seconds, causes the exact same segmentation fault when executing 'usleep(2000000)'!
I'll copy the back trace of the core dump below for both 'pthread_join' and 'usleep'.

pthread_join:

#0  0x00007fff8343aa6a in __semwait_signal ()
#1  0x00007fff83461896 in pthread_join ()
#2  0x000000010000179d in Controller::cleanup () at src/native/osx/controllers.cpp:335
#3  0x0000000100008e51 in ControllersTest::performTest (this=0x100211bf0) at unittests/src/controllers_test.cpp:70
#4  0x000000010000e5b9 in main (argc=2, argv=0x7fff5fbff980) at unittests/src/verify.cpp:34

usleep(2000000):

#0  0x00007fff8343aa6a in __semwait_signal ()
#1  0x00007fff8343a8f9 in nanosleep ()
#2  0x00007fff8343a863 in usleep ()
#3  0x000000010000177b in Controller::cleanup () at src/native/osx/controllers.cpp:335
#4  0x0000000100008e3d in ControllersTest::performTest (this=0x100211bf0) at unittests/src/controllers_test.cpp:70
#5  0x000000010000e5a5 in main (argc=2, argv=0x7fff5fbff980) at unittests/src/verify.cpp:34

Any help will be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沫雨熙 2024-12-15 18:59:03

看来 threadHandler 内的 while 循环之后的代码导致了段错误。如果在线程内生成信号(例如 SIGSEGV),则进程本身将被终止。

尝试使用 GDB 和 thread apply all bt 来获取所有线程的回溯。

It seems that the code after your while loop inside the threadHandler is causing a segfault. If a signal is generated (e.g. SIGSEGV) inside a thread, the process itself will get killed.

Try using GDB and thread apply all bt in order to get backtrace for all threads.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文