C++ 使用无效套接字调用boost::asio::write()使我的Blackberry 10应用程序崩溃

C++ 使用无效套接字调用boost::asio::write()使我的Blackberry 10应用程序崩溃,c++,sockets,boost,blackberry-10,compiler-optimization,C++,Sockets,Boost,Blackberry 10,Compiler Optimization,这篇文章讲述了在最近的一个软件项目中遇到的一个技术问题,并允许读者从来之不易的问题解决方案中获益 背景 在我的公司,我是一个内部库的实现者和维护者,该库使用来实现通过套接字的跨平台数据传输。最近,一位同事向我提出了以下问题:她的黑莓10应用程序链接并使用了我的库,如果在文件传输过程中不小心关闭了Wi-Fi路由器,它会在几秒钟内崩溃 在库中启用内置跟踪向我们表明,当库调用boost::asio::write(boost::asio::ip::tcp::socket*,boost::asio::bu

这篇文章讲述了在最近的一个软件项目中遇到的一个技术问题,并允许读者从来之不易的问题解决方案中获益

背景

在我的公司,我是一个内部库的实现者和维护者,该库使用来实现通过套接字的跨平台数据传输。最近,一位同事向我提出了以下问题:她的黑莓10应用程序链接并使用了我的库,如果在文件传输过程中不小心关闭了Wi-Fi路由器,它会在几秒钟内崩溃

在库中启用内置跟踪向我们表明,当库调用boost::asio::write(boost::asio::ip::tcp::socket*,boost::asio::buffer)函数时发生崩溃,该函数的套接字“无效”(即套接字可能不可用)。在write()周围放置try/catch(boost::system::system_error)块未能捕获任何内容——显然,崩溃发生在boost中

因为崩溃只发生在发布版本中,所以我们无法使用调试器

技术信息

  • QNX编译器QCC使用GNU4.6.3
  • 使用的Boost版本是1.48.0
以下是编译器的典型命令行调用:

/home/foobar/bbndk/host_10_1_0_238/linux/x86/usr/bin/QCC
    -Vgcc_ntoarmv7le
    -lang-c++
    -x c++
    -DLINUX -DQNX -DSUPPORT_LAN -DUSE_SQLITE_FOR_DATABASE
    -Wno-psabi -Wno-write-strings
    -O3
    -DNDEBUG
    -fno-strict-aliasing
    -fPIC
    -I/home/foobar/Libraries/BlackBerry_10/boost_1.48/include
    ...
    -I/home/foobar/Libraries/BlackBerry_10/utfcpp_1.0/include
    -o CMakeFiles/Internals.dir/ConfigFileSingleton.cpp.o
    -c /home/foobar/myproject_dev/myproject/SDK/Internals/ConfigFileSingleton.cpp
用于定位问题源的步骤

我们编写了一个轻量级的最小化应用程序,尝试用更少的代码重现问题,首先使用原始套接字,然后使用Boost的ASIO。如果崩溃发生,我们可以假设问题不是由我们的专有库引起的。不幸的是,这次事故无法再现,导致我们怀疑我们的图书馆出了问题

我们编写了一个轻量级跟踪框架,用于Boost的ASIO头文件,检测与问题相关的函数。框架在进入和退出这些函数时输出一个字符串,使我们能够跟踪变量的值

使用跟踪框架,我们能够证明崩溃发生在boost::throw_exception()模板函数中(删除了不相关的ifdef代码)。当系统级写入操作在“断管”上失败时,Boost调用此函数:

鉴于此次碰撞,建议谨慎使用“-O3”。我们的minimal应用程序之所以没有重现这个问题,是因为它是使用优化级别2而不是3编译的


我们正在寻找提交给QNX和/或GNU团队的解决方案。

完整的解决方案描述可以在上面的问题中找到。根据Dale的指示,我在这里提供了解决方案的简要说明

此次崩溃是由于使用默认的优化级别3为Blackberry编译Boost造成的。一旦我们将优化级别从-O3降至-O2,崩溃就消失了


此后,我们修改了QNX工具链中的Blackberry.cmake文件,使用“-O2”而不是原来的“-O3”。鉴于此故障,建议谨慎使用“-O3”。

请输入您的解决方案作为答案,这样就不会出现在“未回答的问题”中。回答您自己的问题被视为“一件好事”关于StackOverflow,当问题的目的是分享知识时。@Dale感谢您的提醒和指导。我将发布一个非常简短的解决方案摘要,作为防止“未回答问题”问题的答案,并将在将来做“正确的事情”。再次感谢。
template<class E> BOOST_ATTRIBUTE_NORETURN inline void throw_exception( E const & e )
{
    //All boost exceptions are required to derive from std::exception,
    //to ensure compatibility with BOOST_NO_EXCEPTIONS.
    throw_exception_assert_compatibility(e);
    throw enable_current_exception(enable_error_info(e));
}
SET(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG")
#SET(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
. . .
SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG -fno-strict-aliasing -fPIC")
#SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -fno-strict-aliasing -fPIC")