【问题标题】:Unhandled forced unwind causes abort未处理的强制展开导致中止
【发布时间】:2011-06-13 14:22:05
【问题描述】:

所以我对pthread_exitpthread_cancel 的理解是,它们都会导致在目标线程的相关堆栈帧中抛出一个类似异常的东西,称为“强制展开”。这可以被捕获以进行特定于线程的清理,但必须重新抛出,否则我们会在未重新抛出的 catch 块末尾得到一个隐含的abort()

pthread_cancel 的情况下,根据线程的取消状态和类型,在接收到相关信号时立即发生,或者在下一次进入取消点时,或者在下一次解除阻塞信号时发生。

pthread_exit 的情况下,调用线程立即进行强制展开。

很好。这种“异常”是杀死线程过程的正常部分。那么,为什么即使我重新抛出它,它也会导致 std::terminate() 被调用,从而中止我的整个应用程序?

请注意,我多次捕获并重新抛出异常。

另请注意,我从SIGTERM 信号处理程序中调用pthread_exit。这在我的玩具测试代码中运行良好,使用 g++ 4.3.2 编译,它有一个线程运行signal(SIGTERM, handler_that_calls_pthread_exit),然后坐在一个紧密的while 循环中,直到它得到TERM 信号。但它在实际应用中不起作用。

相关堆栈帧:

(gdb) where
#0  0x0000003425c30265 in raise () from /lib64/libc.so.6
#1  0x0000003425c31d10 in abort () from /lib64/libc.so.6
#2  0x00000000012b7740 in sv_bsd_terminate () at exception_handlers.cpp:38
#3  0x00002aef65983aa6 in __cxxabiv1::__terminate (handler=0x518)
    at /view/ken_gcc_4.3/vobs/Compiler/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:43
#4  0x00002aef65983ad3 in std::terminate ()
    at /view/ken_gcc_4.3/vobs/Compiler/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:53
#5  0x00002aef65983a5a in __cxxabiv1::__gxx_personality_v0 (
    version=<value optimized out>, actions=<value optimized out>, 
    exception_class=<value optimized out>, ue_header=0x645bcd80, 
    context=0x645bb940)
    at /view/ken_gcc_4.3/vobs/Compiler/gcc/libstdc++-v3/libsupc++/eh_personality.cc:657
#6  0x00002aef6524d68c in _Unwind_ForcedUnwind_Phase2 (exc=0x645bcd80, 
    context=0x645bb940)
    at /view/ken_gcc_4.3/vobs/Compiler/gcc/libgcc/../gcc/unwind.inc:180
#7  0x00002aef6524d723 in _Unwind_ForcedUnwind (exc=0x645bcd80, 
    stop=<value optimized out>, stop_argument=0x645bc1a0)
    at /view/ken_gcc_4.3/vobs/Compiler/gcc/libgcc/../gcc/unwind.inc:212
#8  0x000000342640cf80 in __pthread_unwind () from /lib64/libpthread.so.0
#9  0x00000034264077a5 in pthread_exit () from /lib64/libpthread.so.0
#10 0x0000000000f0d959 in threadHandleTerm (sig=<value optimized out>)
    at osiThreadLauncherLinux.cpp:46
#11 <signal handler called>

谢谢!

埃里克

【问题讨论】:

    标签: c++ exception pthreads terminate abort


    【解决方案1】:

    请注意,我正在打电话 pthread_exit 退出我的 SIGTERM 信号 处理程序。

    这是你的问题。引用 POSIX 规范 (http://pubs.opengroup.org/onlinepubs/009695399/functions/signal.html):

    如果信号的出现不是调用 abort()、raise()、kill()、pthread_kill() 或 sigqueue() 的结果,如果信号处理程序的行为未定义指具有静态存储持续时间的任何对象,而不是通过将值分配给声明为 volatile sig_atomic_t 的对象,或 如果信号处理程序调用标准库中的任何函数,而不是 Signal Concepts 中列出的函数之一。强>

    http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html#tag_02_04_03 给出了允许的函数列表,不包括pthread_exit()。因此,您的程序表现出未定义的行为。

    我能想到三个选择:

    1. 在信号处理程序中设置一个标志,由线程定期检查,而不是尝试直接从信号处理程序退出。
    2. 使用sigwait() 显式等待独立线程上的信号。然后,该线程可以在您希望退出的线程上显式调用pthread_cancel()
    3. 屏蔽信号,并在要退出的线程上定期调用sigpending(),如果信号处于未决状态则退出。

    【讨论】:

      猜你喜欢
      • 2018-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多