• 【C++】统计代码覆盖率(四)


    补充如下内容:

    1. 配置 GCC 环境 支持 C++ 11 regex代码编译

    2. 更换一种 (二) 中 修改编译脚本方式 使用 scons 提供的 SConstruct 编译

    一  centos 安装devtoolset-3

    该篇幅转自:http://www.openskill.cn/article/372

    背景:由于gcc 4.8.2不支持C++11的regex库,故需升到4.9.2。

    1  cat /etc/issue,确认服务器 CeotOS 是哪个系列

    centos6系列
    # wget https://www.softwarecollections.org/repos/rhscl/devtoolset-3/epel-6-x86_64/noarch/rhscl-devtoolset-3-epel-6-x86_64-1-2.noarch.rpm
    # rpm -ivh rhscl-devtoolset-3-epel-6-x86_64-1-2.noarch.rpm
    # wget https://copr.fedoraproject.org/coprs/rhscl/devtoolset-3/repo/epel-6/rhscl-devtoolset-3-epel-6.repo && mv ./*.repo /etc/yum.repos.d/
    centos7系统
    # wget https://www.softwarecollections.org/repos/rhscl/devtoolset-3/epel-7-x86_64/noarch/rhscl-devtoolset-3-epel-7-x86_64-1-2.noarch.rpm
    # rpm -ivh rhscl-devtoolset-3-epel-7-x86_64-1-2.noarch.rpm

    2 安装命令如下

    yum --disablerepo='*' --enablerepo='rhscl-devtoolset-3' install devtoolset-3-gcc devtoolset-3-gcc-c++ devtoolset-3-toolchain -y
    # 如果报错见 报错与解决 部分

    3 启用该版本GCC

    scl enable devtoolset-3 bash #类似于python虚拟环境,不影响其他版本使用者
    或者如下:
    find / -name "devtoolset-3" # 找到 devtoolset-3 的安装目录
    [root@105 /opt/rh]$ source devtoolset-3/enable # 激活
    [root@105 /opt/rh]$ gcc -v
    Using built-in specs.
    ...
    gcc version 4.9.2 20150212 (Red Hat 4.9.2-6) (GCC)

    4 替换编译文件变量

    # export CC=/opt/rh/devtoolset-3/root/usr/bin/gcc
    # export CPP=/opt/rh/devtoolset-3/root/usr/bin/cpp
    # export CXX=/opt/rh/devtoolset-3/root/usr/bin/c++

     5 问题与解决

    ①在步骤2安装中,报错:

    [/opt/xiaoming/workspace/src]$ yum --disablerepo='*' --enablerepo='rhscl-devtoolset-3' install devtoolset-3-gcc devtoolset-3-gcc-c++ devtoolset-3-toolchain -y
    Loaded plugins: fastestmirror, security

    Error getting repository data for rhscl-devtoolset-3, repository not found

    原因:不知道,没查

    解决:替换安装命令为 yum install devtoolset-3-toolchain

    二 使用 scons 提供的 SConstruct 编译

    scons是linux下的自动构建工具,类似cmake。该命令可执行的条件  python 命令可执行 && 安装 scons 工具

    1 安装 scons 工具

       yum install scons

    2 配置 SConstruct 文件 

    utest = ARGUMENTS.get('utest', 'true')
    if utest == 'true':
       env['CXXFLAGS'] += ['-DUTEST']
       env['CXXFLAGS'] += ['-fprofile-arcs']
       env['CXXFLAGS'] += ['-ftest-coverage']
       env.Append(dynamic_libs='-Lartifacts/lib -lcares -Wl,-Bdynamic -lgcov -lm -lc -lrt -ldl')   #主要是这几句
    else:
       env.Append(dynamic_libs='-Lartifacts/lib -lcares -Wl,-Bdynamic -lm -lc -lrt -ldl')

    3 scons -D . 编译文件

    4 检查源码文件夹,包含以下文件

    -rw-r--r--. 1 root root  172K Jun  8 10:19 fb.gcno   #源文件,与gcda合并可统计到覆盖率
    -rw-r--r--. 1 root root  1.3M Jun  8 10:19 fb.o
    -rwxr-xr-x. 1 root root   42M Jun  8 10:22 fb        # 可执行文件

    5 生成gcda文件

      没实际应用,使用./fb 启动文件即可在目录下生成对应 gcda 文件

      正常执行用例应该也能生成,但是有同学反馈没有生成,由于担心环境冲突影响,我没有试。

    6 合并 gcda 和 gcno

    artifacts/bin/lcov/usr/bin/lcov -b ./ --capture --directory src --gcov-tool gcov --output-file alla.info
    lcov命令装在了 artifacts...目录下
    -b 指定 base directory,后面的文件需要在这个目录内
    --capture Capture coverage data 捕获

    三 统计与集成

    同【C++】统计代码覆盖率(三)一致

    四 错误与解决

    ① 使用 scons -D . 命令编译报错

       解决:注意此处报错需要的python版本是 python27。因此要到python27执行  pip install gevent-1.1.2-cp27-cp27mu-manylinux1_x86_64.whl。

       该问题实际没解决,但未影响编译,奇奇怪怪。

    [root@localhost# scons -D .
    ...
    gevent-1.1.2-cp27-cp27mu-manylinux1_x86_64.whl is not a supported wheel on this platform.
    usage: easy_install [options] requirement_or_url ...
       or: easy_install --help

     ② 当前环境不支持 --user 安装

    Can not perform a '--user' install. User site-packages are not visible in this virtualenv.

    原因:--user 的目的与 虚拟环境相同,因此不支持这种使用。但是非常奇怪,因为 python3 是支持的。

    解决:没解决,②和①报的是一个问题的错误,忽略对编译结果没影响。

    ③ 执行编译时报错   #先忽略了其他错误

    [root@105 ...]$ scons -D . 
    ...
    cc1plus: error: -fsanitize=address and -fsanitize=kernel-address are incompatible with -fsanitize=thread
    scons: *** [src/***.o] Error 1
    scons: building terminated because of errors.

    原因:GNU GCC提供的关于sanitize的编译选项之一 -fsanitize=address

    当ASAN_OPTIONS环境变量设置为help=1时(如:ASAN_OPTIONS=help=1),所有可用的选项将在将在程序启用时显示。ASAN_OPTIONS环境变量不能结合-fsanitize=thread使用。

    解决:在编译文件 SConstruct 中注释掉 env['CXXFLAGS'] += ['-fsanitize=thread'] 即可,实际也没用,开发估计瞎写

    ④ 在 GCC V4.9.2 编译报错

    /opt/xiaoming/workspace/tool/workspace/tool.cpp:152: undefined reference to `__asan_before_dynamic_init'
    /opt/xiaoming/workspace/tool.cpp:15: undefined reference to `__ubsan_handle_type_mismatch'
    /opt/xiaoming/workspace/tool.cpp:15: undefined reference to `__ubsan_handle_add_overflow'
    /opt/xiaoming/workspace/tool.cpp:15: undefined reference to `__ubsan_handle_type_mismatch'

    原因:使用 ubsan 检测代码时的问题?一般需要忽略一些东西,比如添加 '-fsanitize=undefined',但实际未生效,可能原因如下:

    https://www.codenong.com/31803705/

    1 我已经安装了 libubsan0 和 lib64ubsan0 并添加了 -lubsan 选项,并且我的应用程序已成功编译!
    2 "GCC recently (version 4.9) gained Undefined Behavior Sanitizer (ubsan), a run-time checker for the C and C++ languages. In order to check your program with ubsan, compile and link the program with -fsanitize=undefined option."
    将-fsanitize=undefined传递给了meson.add_project_arguments(),但是 那些只交给编译器; 我还需要将其传递给meson.add_project_link_arguments()。 添加之后,错误消失了,程序链接了。

    实际解决:注释掉了代码中的如下部分,编译成功了,怀疑开发并实际编译时也是注释掉该部分并没有解决问题。

    build_type = ARGUMENTS.get('build', 'debug')
    if build_type.lower() == 'debug':
      env['CXXFLAGS'] += ['-g']
      #env['CXXFLAGS'] += ['-fsanitize=address']  
      #env['CXXFLAGS'] += ['-fsanitize=thread']    #注释掉以防编译冲突
      #env['CXXFLAGS'] += ['-fno-omit-frame-pointer']
      #env['CXXFLAGS'] += ['-fsanitize=leak']
      #env['CXXFLAGS'] += ['-fsanitize=undefined']
    else:
      env['CXXFLAGS'] += ['-O3']

    ⑤ 生成 info 文件时报错

    [root@105 /opt/xiaoming/workspace]$ artifacts/bin/lcov/usr/bin/lcov -b ./ --capture --directory src --gcov-tool /usr/bin/gcov --output-file alla.info
    Capturing coverage data from src
    Found gcov version: 4.4.7
    Scanning src for .gcda files ...
    Found 49 data files in src
    Processing ssp_service_v2/preload_session.gcda
    Auto-detected compatibility mode for split checksum .gcno file format
    /opt/xiaoming/***.gcno:version '409R', prefer '404R'
    
    out of memory allocating 25868243408 bytes after a total of 14941280 bytes    # 报错
    geninfo: ERROR: GCOV failed for /opt/xiaoming/***.gcda!

    原因:gcc 和 gcov 版本对不上所致

    解决:/usr/bin/gcov --version 是4.4.7,gcc 4.9.2;试了下gcov 版本4.9.2是可以生成info文件了。

    ⑥ 编译后启动服务报错 

    terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::program_options::unknown_option> >'
      what():  unrecognised option
    Aborted (core dumped)

    原因:不知道,很奇怪。

    a 启动命令中有 redis 密码等 会识别不了,加'' ok,报错误b

    b 报贴出来的图样错误,据说是对应代码需要调整,开发同学调整后 ok

    ⑦其他问题

    问题:鉴于有多个模块共用一个 git 地址,且各模块归属不同的开发负责,经常在统计 html 报告时由于模块 A 部署分支,没有模块B编译时的源码文件等问题导致html报告生成失败( xml 不会失败)

    建议:基于以上问题,有以下几种处理方式

    1. 统计分离:git目录只用来拉取代码,拷贝模块的源码文件到其他目录编译统计(同时对通用模块common改动,可手动更新)
    2. 提测分支统一:推动开发解决 -- 此时要保证提测时拉取的分支从 master 拉取
    3. 不解决,单独部署模块,单独查看覆盖率 -- 鉴于自动化用例是全量执行,还是不建议该措施

    综上,最推荐方式1,因为想要指望开发是没用的,测试要时刻靠自己。

  • 相关阅读:
    ES7/ES8 语法学习
    JavaScript中this对象原理简洁说明
    浅谈http协议
    各个浏览器之间常见的兼容性问题
    npm -v 报错:cannot find module 'core-util-is'
    对象遍历的几种方法
    Vue项目如何关闭Eslint检测
    axios 基本运用
    如何去掉vue路由中的#
    vue 父子组件、兄弟组件传值
  • 原文地址:https://www.cnblogs.com/zhaoxd07/p/13037484.html
Copyright © 2020-2023  润新知