zoukankan      html  css  js  c++  java
  • std::cout segmentation fault

    今天测试功能,发现一个奇怪的问题,std::cout导致崩溃。调用过程如下图:

    gdb调试coredump文件,堆栈信息如下图:

     定位具体崩溃日志,发现std::basic_ostream对象没有初始化,如图

     通过谷歌查资料,发现有一个报错跟我类似,根据答复,发现问题出在ios_base::Init没有初始化,

     

    ios_base::Init用于构造此成员类型的对象,确保标准流对象(cin,cout,cerr,clog,cin,cout,cerr和clog)被构造和正确初始化。
    根据答复,只需要include <iostream>便可以保证ios_base::Init初始化
    在C++03中,std::ios_base::Init是未指定的,我们需要确保在输入main()时,标准流已初始化。
    C++11修复这个问题,#include <iostream>的每个实例都跟着static std::ios_base::Init __unspecified_name__,这样可以自动保证流可以使用。
    我检查程序,发现程序中已经#include <iostream>,应该不存在ios_base::Init没有初始化这种情况
    怀疑是dlopen的操作机制影响了ios_base::Init的初始化

    函数定义 void * dlopen(const char* pathName, int mode);
    pathName 指的是db文件或listDB.so文件在实机环境中的位置, mode指的是打开数据库的模式
    mode在linux下,按功能有以下几种
    解析方式
    RTLD_LAZY:
        暂缓决定,在dlopen返回前,对于动态库中的未定义的符号不执行解析,只对函数引用有效,对于变量引用总是立即解析。这种模式有一个优势,
    例如动态库中的某些函数引用了其他第三方库,有些没有,那么调用没有引用第三方库的函数时,可以不用把第三方库的文件放在LD_LIBRARY_PATH下面 RTLD_NOW: 立即决定,在dlopen返回前,解析出所有未定义的符号,如果解析不出来,在dlopen会返回NULL,错误为 undefined symbol:XXX... 作用范围 RTLD_GLOBAL: 动态库中定义的符号可被其后打开的其他库重定位 RTLD_LOCAL: 与RTLD_GLOBAL作用相反,动态库中定义的符号不能被其后打开的其他库重定位。如果没有指明是RTLD_GLOBAL还是RTLD_LOCAL,那么默认是RTLD_LOCAL。 作用方式 RTLD_NODELETE:在dlclose()期间不卸载库,并且在以后使用dlopen()重新加载库时不初始化库中的静态变量。这个flag不是POSIX
    -2001标准。 RTLD_NOLOAD: 不加载库,可用于测试库是否已经加载(dlopen()返回NULL说明未加载,否则说明加载),也可用于改变已加载库的flag,
    如:先前加载库的flag为RTLD_LOCAL,用dlopen(RTLD_NOLOAD
    |RTLD_GLOBAL)后flag将变成RTLD_GLOBAL.这个flag不是POSIX-2001标准 RTLD_DEEPBIND:在搜索全局符号前先搜索库内的符号,避免同名符号的冲突,这个flag不是POSIX-2001标准

    当dlopen中使用RTLD_DEEPBIND特性,可能会屏蔽全局std::ios_base::Init变量,导致iostream对象没有初始化,

    经过实验,在dlopen中取消RTLD_DEEPBIND,崩溃问题得到解决。

     

  • 相关阅读:
    PHP 指定的 CGI 应用程序由于未返回完整的一组 HTTP 头而产生错误行为。
    BPM触发事件
    封装继承多态到底讲的是什么
    .Net 为什么叫.Net 转载自 jerrylsxu 的博客
    C# 琐碎记忆 Message
    SQL Case
    C# 命名规范(部分)
    C# 反射
    C# 日志 log 配置文件
    C# 琐碎记忆 三元表达式
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/15750764.html
Copyright © 2011-2022 走看看