編譯鏈接實戰(22)C/C++代碼覆蓋率統計報告生成

Gcov 查看代碼覆蓋率

文章目錄

    • GCOV 工具簡介
    • gcov 使用
    • lcov
    • 相關編譯選項

GCOV 工具簡介

gcov是一個測試代碼覆蓋率的工具,它是 gcc 自帶的查看代碼覆蓋率的工具。

與GCC結合使用,可以分析您的程序以幫助創建更高效、運行更快的代碼,并發現程序中未經測試的部分。您可以將gcov作為性能分析工具使用,以幫助發現優化工作對代碼產生最佳效果的位置。您還可以將gcov與另一種性能分析工具gprof一起使用,以評估代碼的哪些部分使用了最多的計算時間。

性能分析工具可以幫助您分析代碼的性能。使用像gcov或gprof這樣的分析器,您可以找出一些基本的性能統計數據,例如:

  • 每行代碼執行了多少次
  • 實際執行了哪些代碼行
  • 每個代碼段使用了多少計算時間

一旦您了解了編譯后的代碼如何工作,就可以查看每個模塊,看看哪些模塊應該進行優化。gcov可以幫助您確定在哪里進行優化工作。

軟件開發人員還結合測試套件使用覆蓋率測試,以確保軟件實際上足夠好,可以發布。測試套件可以驗證程序按預期工作;覆蓋率程序測試測試套件執行了程序的多少部分。然后,開發人員可以確定需要向測試套件中添加哪些類型的測試用例,以創建更好的測試和更好的最終產品。

如果您計劃使用gcov,應該在不優化的情況下編譯代碼,因為通過將一些代碼行組合成一個函數的優化,可能無法為您提供尋找“熱點”所需的信息,即代碼使用大量計算時間的地方。同樣,因為gcov按行(最低分辨率)累積統計數據,它最適合一種編程風格,即每行只放置一個語句。如果您使用復雜的宏,這些宏展開為循環或其他控制結構,統計數據就不那么有用——它們只報告宏調用出現的行。如果您的復雜宏表現得像函數,您可以用內聯函數替換它們來解決這個問題。

gcov創建一個名為sourcefile.gcov的日志文件,指示源文件sourcefile.c的每一行執行了多少次。您可以將這些日志文件與gprof一起使用,以幫助微調程序的性能。gprof提供您可以與從gcov獲得的信息一起使用的計時信息。

gcov僅適用于用GCC編譯的代碼。它與任何其他性能分析或測試覆蓋機制不兼容。

使用效果如下圖所示:

img

程序運行完成后,可以查看每個文件的代碼覆蓋率情況,上面報告中展示了每個文件的行覆蓋率,函數覆蓋率和分支覆蓋率。

打開一個文件的覆蓋率報告,頁面對開始有文件的基本信息描述,以 FreeRTOS 的 task.c 為例,它的有效代碼行數為 921 行,共 24 個函數(幾千行的文件其實也沒多少嘛~)

img

img

在覆蓋率的正文,有該文件的完整代碼,并用不同顏色進行高亮標注了:

  • 藍色表示運行被覆蓋的代碼,前面的數字表示代碼執行次數。
  • 紅色表示未執行代碼。
  • 白色表示無效代碼,包括注釋,空行和未編譯代碼。

gcov 使用

使用 gcov 的流程非常簡單,只需要三步即可。 下面以 hello world 為例,展示生成覆蓋率報告。

代碼如下:

//main.c#include <stdio.h>int main(int argc, char **argv) {printf("hello world\n");return 0;
}

第一步: 添加編譯參數 -fprofile-arcs -ftest-coverage

在所需要的生產覆蓋率的文件中,添加編譯參數,編譯代碼生成目標文件,同時會生成 *.gcno 文件,其中包含文件的行號等信息。
GCC C/C++代碼覆蓋率統計生成

gcc main.c -c -fprofile-arcs -ftest-coverage -o main.o
ls # 輸出文件列表:
# main.c  main.gcno  main.o
gcc main.o -lgcov -o main

第二步: 添加鏈接參數 -lgcov ,運行程序

運行程序后,會生成一個 *.gcda 文件,里面包含代碼執行次數等數據。

gcc main.o -lgcov -o main
# 運行程序
./main
# hello world
ls # 輸出文件列表:
#main  main.c  main.gcda  main.gcno  main.o

第三步: 輸出覆蓋率報告 使用下面命令輸出覆蓋率報告

# 第一次使用前安裝工具
sudo apt install lcov# 生成覆蓋率文本報告
lcov -c -d . -o test.info --rc lcov_branch_coverage=1 
# 生成覆蓋率網頁報告
genhtml --branch-coverage -o result test.info 

輸入上面兩/三條命令后在,執行命令的文件路徑可以看到一個 result 文件夾,在里面就是對應的網頁覆蓋率報告。

img

用瀏覽器打開 index.html 就可以看到最開始展示的覆蓋率信息了。

lcov

lcov 是 GCC 覆蓋率測試工具 gcov 的圖形化前端,用于收集多個源文件的行、函數和分支覆蓋率數據,并創建包含覆蓋信息的 HTML 頁面。它還添加了概覽頁面,以便在文件結構中進行方便的導航。

使用 lcov 收集覆蓋率數據,并使用 genhtml 創建 HTML 頁面。覆蓋率數據可以從當前正在運行的 Linux 內核或用戶空間應用程序中收集。要做到這一點,您需要完成以下準備步驟:

  1. 收集覆蓋率數據:首先,使用 lcov 工具來收集代碼的覆蓋率數據。您可以通過在編譯時添加 -ftest-coverage-fprofile-arcs 選項來生成覆蓋率數據的中間文件。然后,通過運行應用程序或測試套件來執行代碼路徑,以便生成覆蓋率數據。
  2. 生成 HTML 頁面:接下來,使用 genhtml 工具將收集到的覆蓋率數據轉換為 HTML 頁面。genhtml 將分析覆蓋率數據,并生成帶有覆蓋信息注釋的源代碼的 HTML 頁面,以及用于導航文件結構的概覽頁面。

這些工具的結合使用使得開發人員能夠更直觀地查看代碼的覆蓋情況,從而更好地理解測試覆蓋范圍和質量。通過分析生成的 HTML 頁面,開發人員可以識別哪些部分的代碼需要更多的測試覆蓋,以及哪些部分已經得到了良好的覆蓋。

總的來說,lcov 和 genhtml 工具的組合為開發人員提供了一種強大的方式來收集和可視化代碼覆蓋率數據,從而幫助他們更好地進行測試和代碼質量管理。如果您需要進一步解釋或有其他問題,請隨時告訴我,我很樂意為您提供幫助。

關鍵選項:

   -r tracefile pattern--remove tracefile patternRemove data from tracefile.Use this switch if you want to remove coverage data for a particular set of files from a tracefile. Additional command line parameters will be interpreted as  shell  wildcard  patterns  (notethat they may need to be escaped accordingly to prevent the shell from expanding them first).  Every file entry in tracefile which matches at least one of those patterns will be removed.Note: The pattern must be specified to match the absolute path of each source file.The result of the remove operation will be written to stdout or the tracefile specified with -o.Only one of  -z, -c, -a, -e, -r, -l, --diff or --summary may be specified at a time.--exclude patternExclude source files matching pattern.Use this switch if you want to exclude coverage data for a particular set of source files matching any of the given patterns. Multiple patterns can be specified by  using  multiple  --excludecommand line switches. The patterns will be interpreted as shell wildcard patterns (note that they may need to be escaped accordingly to prevent the shell from expanding them first).Note: The pattern must be specified to match the absolute path of each source file.Can be combined with the --include command line switch. If a given file matches both the include pattern and the exclude pattern, the exclude pattern will take precedence.
 --include patternInclude source files matching pattern.Use this switch if you want to include coverage data for only a particular set of source files matching any of the given patterns. Multiple patterns can be specified by using  multiple  --in‐clude command line switches. The patterns will be interpreted as shell wildcard patterns (note that they may need to be escaped accordingly to prevent the shell from expanding them first).Note: The pattern must be specified to match the absolute path of each source file.
       --rc keyword=valueOverride a configuration directive.Use  this option to specify a keyword=value statement which overrides the corresponding configuration statement in the lcovrc configuration file. You can specify this option more than once tooverride multiple configuration statements.  See lcovrc(5) for a list of available keywords and their meaning.

相關編譯選項

  • -fprofile-arcs

該選項用于在程序執行時對程序流程弧進行插裝,記錄每個分支和調用被執行的次數以及它們被取或返回的次數。對于支持具有優先級支持的構造函數的目標,剖析能夠正確處理構造函數、析構函數以及用作全局變量類型的類的C++構造函數(和析構函數)。

當編譯后的程序退出時,會將這些數據保存到名為 auxname.gcda 的文件中,每個源文件都會生成一個相應的 .gcda 文件。這些數據可以用于基于profile-directed 的優化(例如 -fbranch-probabilities),或者用于測試覆蓋率分析(例如 -ftest-coverage)。每個目標文件的 auxname 是從輸出文件的名稱生成的,如果顯式指定了輸出文件并且它不是最終可執行文件,則 auxname 會采用源文件的基本名稱。在這兩種情況下,任何后綴都會被移除(例如對于輸入文件 dir/foo.cauxnamefoo.gcda;對于指定為 -o dir/foo.o 的輸出文件,auxnamedir/foo.gcda)。

簡而言之,通過使用 -fprofile-arcs 編譯選項,您可以收集程序在執行過程中的代碼覆蓋率和執行路徑信息,從而可以進行優化或測試覆蓋率分析。

  • –coverage

這個選項是 -fprofile-arcs -ftest-coverage(編譯時)和 -lgcov(鏈接時)的同義詞。主要做了以下工作:

  1. 使用 -fprofile-arcs 和優化、代碼生成選項來編譯源文件。對于測試覆蓋率分析,還需額外加上 -ftest-coverage 選項。并不需要對程序中的每個源文件都進行剖析。
  2. 另外使用 -fprofile-abs-path 選項來編譯源文件,以在 .gcno 文件中創建絕對路徑名。這樣可以讓 gcov 在項目中的編譯發生在不同工作目錄的情況下正確找到源文件。
  3. 使用 -lgcov-fprofile-arcs(后者暗含了前者)來鏈接您的目標文件。
  4. 運行程序以生成弧剖析信息。可以多次重復這個過程。您可以同時運行多個程序實例,只要文件系統支持鎖定,數據文件就會被正確地更新。除非啟用了嚴格的 ISO C 方言選項,否則 “fork” 調用會被檢測并正確處理,而不會重復計數。
  5. 對于基于profile-directed的優化,需要使用相同的優化和代碼生成選項再次編譯源文件,并加上 -fbranch-probabilities
  6. 對于測試覆蓋率分析,使用 gcov 從 .gcno.gcda 文件中生成人類可讀的信息。請參考 gcov 文檔以獲取更多信息。
    特殊環境使用注意點:

在正常使用 gcov 是非常簡單的,但是在特殊項目中使用 gcov 需要注意一些坑,否則就會跟我一樣掉進去出不來。。。

  • 鏈接時,會在 .init_array 段插入 __gcov_init() 函數,該函數在 main 運行之前初始化 gcov 運行環境。
  • 如果修改過鏈接腳本,注意 .init_array 的全局構造函數是否執行成功。
  • 和上面一樣,鏈接時,會在全局析構函數中插入 __gcov_exit() 函數,在 main 執行結束后,輸出 *.gcda 文件。
  • 如果程序為異常退出,則不會生成 *.gcda 文件,此時需要在代碼適當位置插入 __gcov_flush() 函數,將文件進行保存。
  • 默認狀態 *.gcda 文件和 *.gcno 文件所在文件夾相同,如果需要修改輸出文件夾,可通過添加環境變量:GCOV_PREFIX 和 GCOV_PREFIX_STRIP
  • GCOV_PREFIX_STRIP=16 , 為將原有路徑裁剪16個文件夾。 GCOV_PREFIX=/home/tester/build , 為將裁剪后的路徑添加前綴 例如:上文中默認 main.gcda 所在的文件 /home/tester/main.gcda,裁剪后添加前綴后變為/home/tester/build/main.gcda

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/713691.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/713691.shtml
英文地址,請注明出處:http://en.pswp.cn/news/713691.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PCIE 4.0 L0s/L1/L2

L0是PCIE設備正常工作的狀態&#xff0c;當設備鏈路處于非工作狀態可以跳轉大相應的低功耗狀態&#xff0c;L0s是一種可以快速恢復到L0的低功耗狀態&#xff1b;L1必須經過Reovery狀態才可以恢復到L0狀態&#xff1b;L2需要從Detect開始逐步進入到L0狀態。它們的恢復時間依次延…

麒麟銀河操作系統V10部署ffmpeg(也能用于Linux系統)

麒麟銀河操作系統V10部署ffmpeg(也能用于Linux系統) 部署ffmpeg用來處理視頻的各種操作 想使用ffmpeg&#xff0c;要先安裝nasm&#xff0c;yasm&#xff0c;x264之后&#xff0c;否則會報錯 nkvers 查看麒麟操作系統版本 cat /proc/version #查看linux版本信息 uname -a …

Android修行手冊-Chaquopy中opencv、numpy的初步應用

Unity3D特效百例案例項目實戰源碼Android-Unity實戰問題匯總游戲腳本-輔助自動化Android控件全解手冊再戰Android系列Scratch編程案例軟考全系列Unity3D學習專欄藍橋系列ChatGPT和AIGC &#x1f449;關于作者 專注于Android/Unity和各種游戲開發技巧&#xff0c;以及各種資源分…

SpringBoot源碼解讀與原理分析(三十八)SpringBoot整合WebFlux(一)WebFlux的自動裝配

文章目錄 前言第13章 SpringBoot整合WebFlux13.1 響應式編程與Reactor13.1.1 命令式與響應式13.1.2 異步非阻塞13.1.3 觀察者模式13.1.4 響應性13.1.5 響應式流13.1.6 背壓13.1.7 Reactor13.1.7.1 Publisher13.1.7.2 Subscriber13.1.7.3 Subscription13.1.7.4 Processor13.1.7.…

BF算法實現(Python,C++)

BF算法&#xff0c;即暴力(Brute Force)算法&#xff0c;是普通的模式匹配算法&#xff0c;BF算法的思想就是將目標串S的第一個字符與模式串T的第一個字符進行匹配&#xff0c;若相等&#xff0c;則繼續比較S的第二個字符和 T的第二個字符&#xff1b;若不相等&#xff0c;則比…

Leetcoder Day32| 貪心算法part05

763.劃分字母區間 字符串 S 由小寫字母組成。我們要把這個字符串劃分為盡可能多的片段&#xff0c;同一字母最多出現在一個片段中。返回一個表示每個字符串片段的長度的列表。 示例&#xff1a; 輸入&#xff1a;S "ababcbacadefegdehijhklij"輸出&#xff1a;[9,7…

今日早報 每日精選15條新聞簡報 每天一分鐘 知曉天下事 3月2日,星期六

每天一分鐘&#xff0c;知曉天下事&#xff01; 2024年3月2日 星期六 農歷正月廿二 1、 氣象局&#xff1a;3月份仍有5次冷空氣影響我國&#xff1b;全國多地或提前入春。 2、 央行&#xff1a;將外籍來華人員移動支付單筆交易限額由1000美元提高到5000美元。 3、 神舟十七號航…

全量知識系統問題及SmartChat給出的答復 之8 三套工具之3語法解析器 之1

Q19. 問題 : 解釋單詞解釋單詞occupied 的字典條目 (word-def occupiedinterest 5type EBsubclass SEBtemplate (script $Demonstrateactor nilobject nildemands nilmethod (scene $Occupyactor nillocation nil))fill (((actor) (top-of *actor-s…

【源碼】imx6ull實現觸摸屏單點實驗

一、本實驗實驗的器材&#xff1a; 1.正點原子imx6ull的阿爾法開發板v2.2 2.屏幕ALIENTEK 4.3 RGBLCD 二、實驗已經移植好的文件&#xff1a; 倉庫代碼&#xff1a;https://gitee.com/wangyoujie11/atkboard_-linux_-driver.git 1.文件說明 23_multitouch &#xff1a;驅動代…

aws平臺的ec2實例 GNU/Linux系統安裝docker流程

在AWS EC2實例上安裝Docker的流程與其他GNU/Linux系統基本相同。以下是在AWS EC2實例上安裝Docker的一般步驟&#xff1a; 登錄到AWS EC2實例&#xff1a; 使用SSH或者其他遠程登錄方式登錄到你的GNU/Linux實例。 更新系統包管理器&#xff1a; 對于基于Amazon Linux的系統&am…

常見Prometheus exporter部署

常見Prometheus exporter部署 Prometheus部署Node exporterProcess exporterRedis exporterMySQL exporterOracleDB exporter Prometheus部署 本地部署&#xff1a; wget https://github.com/prometheus/prometheus/releases/download/v*/prometheus-*.*-amd64.tar.gz tar xv…

java的jar打包docker鏡像,啟動加載

測試環境&#xff0c;打包鏡像 1,把jar包復制/data/liu/mssda.jar, cd到這個目錄下 2&#xff0c;創建Dockerfile文件&#xff0c;jdk17版本&#xff0c;內容如下 jdk8版本 FROM openjdk:8-jre-alpine WORKDIR /app COPY . /app CMD ["java", "-jar",…

最大奇約數(c++題解)

內存限制&#xff1a; 128 MiB時間限制&#xff1a; 100 ms標準輸入輸出題目類型&#xff1a; 傳統評測方式&#xff1a; 文本比較 題目描述 定義函數f(x)表示x的最大奇約數&#xff0c;這里x表示正整數。例如&#xff0c;f(20) 5&#xff0c;因為20的約數從小到大分別有&am…

奧地利羅馬尼亞媒體宣發稿對跨境出海推廣新聞營銷的意義

【本篇由言同數字科技有限公司原創】在當今全球化的時代&#xff0c;品牌跨境海外推廣已成為企業拓展國際市場的必要途徑。而奧地利和羅馬尼亞是歐洲重要的市場之一&#xff0c;通過在當地媒體上發表文章&#xff0c;可以幫助品牌成功打入這兩個市場&#xff0c;獲得更多的機會…

【YOLO v5 v7 v8 小目標改進】ODConv:在卷積核所有維度(數量、空間、輸入、輸出)上應用注意力機制來優化傳統動態卷積

ODConv&#xff1a;在卷積核所有維度&#xff08;數量、空間、輸入、輸出&#xff09;上應用注意力機制來優化傳統的動態卷積 提出背景傳統動態卷積全維動態卷積效果 小目標漲點YOLO v5 魔改YOLO v7 魔改YOLO v8 魔改 論文&#xff1a;https://openreview.net/pdf?idDmpCfq6Mg…

leedcode刷題--day7(字符串)

23 文章講解 力扣地址 C class Solution { public:void reverseString(vector<char>& s) {int left 0;int right s.size() - 1; // right 應該初始化為 s.size() - 1while (left < right) {swap(s[left], s[right]); // 直接交換 s[left] 和 s[right] 的值lef…

(學習日記)2024.02.29:UCOSIII第二節

寫在前面&#xff1a; 由于時間的不足與學習的碎片化&#xff0c;寫博客變得有些奢侈。 但是對于記錄學習&#xff08;忘了以后能快速復習&#xff09;的渴望一天天變得強烈。 既然如此 不如以天為單位&#xff0c;以時間為順序&#xff0c;僅僅將博客當做一個知識學習的目錄&a…

WSL2外部網絡設置

1 關閉所有WSL系統 wsl --shutdown 2 打開Hyper-V管理器 3 將“虛擬交換機管理器”-> ”WSL連接類型“設置為“外部網絡” 4 啟動WSL系統&#xff0c;手動修改WSL網絡 將WSL網絡IP修改為192.168.1.9 sudo ip addr del $(ip addr show eth0 | grep inet\b | awk {print $2} |…

FFmpeg+OpenCV開發案例匯總

桌面共享工具&#xff08;軟編版&#xff09; 桌面共享工具&#xff08;DXGI硬編版&#xff09; 智能廣告大屏&#xff08;可疊加透明廣告&#xff09; Android手機屏幕RTMP推流工具&#xff08;推麥克風版&#xff09; Android手機屏幕RTMP推流工具&#xff08;推揚聲器版…

FinalMLP:用于推薦系統的簡單但強大的雙流 MLP 模型

原文地址&#xff1a;FinalMLP: A Simple yet Powerful Two-Stream MLP Model for Recommendation Systems 了解 FinalMLP 如何轉變在線推薦&#xff1a;通過尖端 AI 研究解鎖個性化體驗 2024 年 2 月 14 日 介紹 世界正在向數字時代發展&#xff0c;在這個時代&#xff0c;…