首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用无效套接字调用boost::asio::write()使我的黑莓10应用程序崩溃

使用无效套接字调用boost::asio::write()使我的黑莓10应用程序崩溃
EN

Stack Overflow用户
提问于 2014-02-19 16:12:56
回答 1查看 341关注 0票数 8

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

背景

在我的公司里,我是一个内部库的实现者和维护者,它使用Boost asio ("ASynchronous I/O") socket framework实现跨平台的套接字数据传输。最近,我的一位同事遇到了以下问题:她的黑莓10应用程序连接并使用了我的库,如果with路由器在文件传输操作中被随意关闭,它会在几秒钟内崩溃。

在库中启用内置跟踪告诉我们,当库调用boost::asio::write(boost::asio::ip::tcp::socket *,boost::asio::buffer)函数时,会发生崩溃,而套接字不是“有效”的(即,套接字可能不可用)。在write()周围放置一个try/ catch (boost::system::system_error)块没有捕获任何东西--显然,崩溃是在Boost内发生的。

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

技术信息

  • QNX编译器QCC使用GNU 4.6.3
  • 使用的Boost版本是1.48.0

下面是编译器的典型命令行调用:

代码语言:javascript
复制
/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‘s代码删除)。当系统级写操作在“断管”上失败时,Boost调用此函数:

代码语言:javascript
复制
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));
}

插入跟踪并将“抛出”语句拆分为单独的语句向我们证明,崩溃发生在抛出异常对象的过程中。很可能,当异常被抛出时,堆栈的展开发生了很大的问题。

解决方案

一旦我们意识到它很可能是编译器错误,而不是应用程序级错误,我们就检查了用于构建库的编译器选项。我们排除了内存损坏的可能性,因为Boost内部代码可能已经增强并且足够健壮。一旦我们认为发布模式优化可能是罪魁祸首,那么与解决方案的距离就很短了:将优化级别从-O3降到-O2。

一旦我们这么做了,坠机就消失了。

此后,我们修改了QNX工具链中的Blackberry.cmake文件,使其使用"-O2“,而不是原始的"-O3":

代码语言:javascript
复制
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")

考虑到这种崩溃,谨慎使用"-O3“可能是明智的。我们最小的应用程序没有重现问题的原因是因为它是用优化级别2而不是3编译的。

我们正在寻找一个提交给QNX和/或GNU团队的SSCCE

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-04-19 17:49:27

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

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

此后,我们修改了QNX工具链中的Blackberry.cmake文件,使其使用"-O2“而不是原始的"-O3”。考虑到这种崩溃,谨慎使用"-O3“可能是明智的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21886085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档