• 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,崩溃问题得到解决。

     

  • 相关阅读:
    linux freopen函数
    进程的环境变量environ
    ls -l 和du 的区别
    Python时间,日期,时间戳之间转换
    Web 服务器压力测试实例详解
    装numpy 环境:python3.4+ windows7 +64位系统
    在Windows Python3.4 上安装NumPy、Matplotlib、SciPy和IPython
    apache 自带的ab.exe 测试网站的并发量(网站压力测试)
    成员如何关注微信企业号?
    微信企业号通讯录有什么用?
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/15750764.html
Copyright © 2020-2023  润新知