Undeterministic std::system_error: what(): Operation not permitted
Undeterministic std::system_error: what(): Operation not permitted
我正在尝试 运行 我的程序,偶尔 运行 我会收到一个错误:
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
如何获得有关该问题的更多信息?
首先,您需要查明错误是来自您的函数,该函数被 std::thread
运行 还是来自 std::thread
本身。如果您的函数抛出异常,它将被 std::thread
启动器函数捕获,并调用终止。如果你使你的函数 noexcept
那么 terminate
将在它被捕获之前被调用,你会在堆栈跟踪中看到它从哪里抛出(GCC 的更高版本不会捕获异常,所以这个自动发生)。
如果异常来自 std::thread
本身,则意味着您的程序 link 编辑了 libc.so.6
中 pthread_create
的虚拟定义,而不是真正的定义在 libpthread.so
或 libpthread.a
使用 ldd
查看您的程序是否 linking 到共享 libpthread.so
。如果是,则说明您的工具链有问题(应该使用 libpthread.so
中的定义,而不是 libc.so
中的弱符号)。如果您是静态 linking,您可能需要确保来自 libpthread.a
的所有符号都包含在您的程序中,例如通过使用:
-Wl,--whole-archive -pthread -Wl,--no-whole-archive
N.B。你应该使用 -pthread
而不是 -lpthread
因为这允许 GCC 确保它被放置在 link 命令中的正确位置。
将函数设置为 noexcept 后,我能够找到堆栈跟踪,显示我正在 unique_lock 上调用 condition_variable::wait() 上不存在的互斥量。只是我在其上调用 wait() 的信号量对象为空。因此 system_error 由 unique_lock 抛出,如 https://en.cppreference.com/w/cpp/thread/unique_lock/lock
我正在尝试 运行 我的程序,偶尔 运行 我会收到一个错误:
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
如何获得有关该问题的更多信息?
首先,您需要查明错误是来自您的函数,该函数被 std::thread
运行 还是来自 std::thread
本身。如果您的函数抛出异常,它将被 std::thread
启动器函数捕获,并调用终止。如果你使你的函数 noexcept
那么 terminate
将在它被捕获之前被调用,你会在堆栈跟踪中看到它从哪里抛出(GCC 的更高版本不会捕获异常,所以这个自动发生)。
如果异常来自 std::thread
本身,则意味着您的程序 link 编辑了 libc.so.6
中 pthread_create
的虚拟定义,而不是真正的定义在 libpthread.so
或 libpthread.a
使用 ldd
查看您的程序是否 linking 到共享 libpthread.so
。如果是,则说明您的工具链有问题(应该使用 libpthread.so
中的定义,而不是 libc.so
中的弱符号)。如果您是静态 linking,您可能需要确保来自 libpthread.a
的所有符号都包含在您的程序中,例如通过使用:
-Wl,--whole-archive -pthread -Wl,--no-whole-archive
N.B。你应该使用 -pthread
而不是 -lpthread
因为这允许 GCC 确保它被放置在 link 命令中的正确位置。
将函数设置为 noexcept 后,我能够找到堆栈跟踪,显示我正在 unique_lock 上调用 condition_variable::wait() 上不存在的互斥量。只是我在其上调用 wait() 的信号量对象为空。因此 system_error 由 unique_lock 抛出,如 https://en.cppreference.com/w/cpp/thread/unique_lock/lock