【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,因為想要指望開發是沒用的,測試要時刻靠自己。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM