我正在构建一个在内部使用 Boost.thread 的共享库。因此,Boost.system 也被使用,因为 Boost.thread 依赖于它。我的共享库导出了一个 C 接口,所以我想对最终用户隐藏我所有的内部异常处理和线程使用等。可以这么说,它应该是一个黑匣子。但是,当我与客户端应用程序链接时,虽然程序运行良好 - 一旦通过调用库函数来停止处理,我就会得到:
在抛出“boost::thread_interrupted”实例后调用终止
我在图书馆内部捕获了这个异常,所以我不知道为什么它实际上没有被捕获。最终用户的程序并不意味着以任何方式了解或处理 Boost 异常。在构建共享库时,我对 Boost.thread 和 Boost.system 都使用静态链接,因此外部世界永远不会看到它们。我在 Ubuntu 12 上使用 GCC 4.7。在 Windows 上,我没有这样的问题(MSVC 或 MinGw 都没有)。
(编辑)
根据评论中的要求,我正在编辑问题以显示重现问题的简约示例。
这里首先是 testlib.cpp 和 testlib.h 的代码。
测试库.cpp:
#include <boost/thread/thread.hpp> 无效线程函数() { 而(1) { boost::this_thread::interruption_point(); } } 无效 do_processing() { // 启动一个线程来执行上面的函数。 boost::thread worker(thread_func); // 出于本示例的目的,我们假设线程正确启动。 // 现在让我们中断线程。 worker.interrupt(); // 现在让我们等待它完成。 worker.join(); }
现在 testlib.h:
#ifndef TESTLIB_H #define TESTLIB_H 无效做处理(); #万一
我使用以下命令将其构建到共享库中:
g++ -static-libgcc -static -s -DNDEBUG -I /usr/boost_1_54_0 -L /usr/boost_1_54_0/stage/lib -Wall -shared -fPIC -o libtestlib.so testlib.cpp -lboost_thread -lboost_system -lpthread -O3
然后,我有一个简单的客户端程序的代码,如下所示:
#include “testlib.h” #include <cstdio> 主函数() { 做处理(); printf("执行正确完成。\n"); 返回0; }
我构建客户端如下:
g++ -DNDEBUG -I /usr/boost_1_54_0 -L ./ -Wall -o client client.cpp -ltestlib -O3
当我运行客户端时,我得到:
在抛出“boost::thread_interrupted”实例后调用
终止(核心转储)
我没有明确捕获线程中断异常,但根据 Boost 文档 Boost.thread 会这样做并仅终止给定的线程。我尝试从 thread_func 函数中显式捕获异常,但这没有任何区别。
(编辑结束)
(编辑 2)
值得注意的是,即使打开了 -fexceptions,问题仍然存在。此外,我尝试抛出和捕获一个异常,该异常与捕获和抛出它的代码在同一翻译单元中定义,但没有任何改进。简而言之,所有异常似乎都没有在共享库中被捕获,即使我肯定有它们的捕获处理程序。当我将客户端文件和 testlib 文件编译为单个程序的一部分时,也就是说,没有将 testlib 变成共享库,一切都按预期工作。
(编辑 2 结束)
有小费吗?