【问题标题】:Undeterministic std::system_error: what(): Operation not permitted不确定的 std::system_error: what(): Operation not allowed
【发布时间】:2019-01-15 13:13:02
【问题描述】:

我正在尝试运行我的程序,但在几次运行中出现错误:

terminate called after throwing an instance of 'std::system_error'
  what():  Operation not permitted

我的代码在这里可用:https://github.com/Qabrt/turnstiles

gdb 输出:

Thread 31 "trivial_test" received signal SIGABRT, Aborted.
[Switching to thread 31 (Thread 0x7fff8a7fc700 (LWP 8716))]
#0  0x00007ffff6e7f83b in raise () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff6e7f83b in raise () from /lib64/libc.so.6
#1  0x00007ffff6e81081 in abort () from /lib64/libc.so.6
#2  0x00007ffff78670e5 in __gnu_cxx::__verbose_terminate_handler ()
    at /var/tmp/portage/sys-devel/gcc-7.3.0-r3/work/gcc-7.3.0/libstdc++-v3/libsupc++/vterminate.cc:95
#3  0x00007ffff7864cb6 in __cxxabiv1::__terminate (handler=<optimized out>)
    at /var/tmp/portage/sys-devel/gcc-7.3.0-r3/work/gcc-7.3.0/libstdc++-v3/libsupc++/eh_terminate.cc:47
#4  0x00007ffff7864d01 in std::terminate ()
    at /var/tmp/portage/sys-devel/gcc-7.3.0-r3/work/gcc-7.3.0/libstdc++-v3/libsupc++/eh_terminate.cc:57
#5  0x00007ffff789243f in std::execute_native_thread_routine (__p=0x555555790f80)
    at /var/tmp/portage/sys-devel/gcc-7.3.0-r3/work/gcc-7.3.0/libstdc++-v3/src/c++11/thread.cc:91
#6  0x00007ffff7bbd96a in start_thread () from /lib64/libpthread.so.0
#7  0x00007ffff6f4d11f in clone () from /lib64/libc.so.6

g++ --版本

g++ (Gentoo 7.3.0-r3 p1.4) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

我正在使用 -lpthread 标志进行编译:

/usr/bin/c++    -Wall -Wunused-function -Wwrite-strings -Wformat -Wformat-security -Wparentheses -Wsequence-point -Wno-system-headers -Werror -Winit-self  -g -O0 -fstack-protector-all -D_GLIBXX_DEBUG -D_GLIBXX_DEBUG_PEDANTIC  -rdynamic CMakeFiles/trivial_test.dir/trivial_test.cpp.o  -o trivial_test ../libturnstile_lib.a -lpthread

如何获得有关该问题的更多信息?

【问题讨论】:

  • 你的程序是动态链接到libpthread.so还是静态链接到libpthread.a

标签: c++ c++11 pthreads std-system-error


【解决方案1】:

将函数设置为 noexcept 后,我​​能够找到堆栈跟踪,显示我正在对不存在的互斥锁上的 unique_lock 调用 condition_variable::wait()。只是我调用 wait() 的 Semaphore 对象为空。因此,由 unique_lock 引发的 system_error 与 https://en.cppreference.com/w/cpp/thread/unique_lock/lock 中一样

【讨论】:

    【解决方案2】:

    首先,您需要确定错误是来自std::thread 运行的函数还是来自std::thread 本身。如果您的函数抛出异常,它将被std::thread 启动器函数捕获,并终止将被调用。如果您将函数设为noexcept,那么terminate 将在它被捕获之前被调用,并且您将在堆栈跟踪中看到它是从哪里抛出的(更高版本的GCC 不会捕获异常,所以这会自动发生)。

    如果异常来自std::thread 本身,则意味着您的程序已链接到libc.so.6pthread_create 的虚拟定义,而不是libpthread.solibpthread.a 中的真实定义

    使用ldd 查看您的程序是否链接到共享的libpthread.so。如果是,那么您的工具链有问题(应该使用libpthread.so 中的定义而不是libc.so 中的弱符号)。如果您是静态链接,您可能需要确保来自libpthread.a 的所有符号都包含在您的程序中,例如通过使用:

    -Wl,--whole-archive -pthread -Wl,--no-whole-archive
    

    注意您应该使用-pthread 而不是-lpthread,因为这允许GCC 确保它被放置在链接命令中的正确位置。

    【讨论】:

    • 我发现程序链接正确。在向很多函数添加 noexcept 之后,我终于设法将问题缩小到一行。显然是 unique_lock:“如果没有关联的互斥锁,[抛出] std::system_error 错误代码为 std::errc::operation_not_permitted”。我无法弄清楚为什么没有关联的互斥锁,当它在类 Semaphore 中本地初始化时。
    猜你喜欢
    • 2022-08-19
    • 1970-01-01
    • 2015-09-01
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    • 2019-04-04
    相关资源
    最近更新 更多