3sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/dev-tools/gcovmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Simplified)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/zh_CN/dev-tools/gcovmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/it_IT/dev-tools/gcovmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/ja_JP/dev-tools/gcovmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/ko_KR/dev-tools/gcovmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget"/translations/sp_SP/dev-tools/gcovmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageChinese (Traditional)uh1h hh _documenthsourceNlineNubhwarning)}(hX1此文件的目的是爲讓中文讀者更容易閱讀和理解,而不是作爲一個分支。因此, 如果您對此文件有任何意見或改動,請先嘗試更新原始英文文件。如果要更改或 修正某處翻譯文件,請將意見或補丁發送給維護者(聯繫方式見下)。h]h paragraph)}(hX1此文件的目的是爲讓中文讀者更容易閱讀和理解,而不是作爲一個分支。因此, 如果您對此文件有任何意見或改動,請先嘗試更新原始英文文件。如果要更改或 修正某處翻譯文件,請將意見或補丁發送給維護者(聯繫方式見下)。h]hX1此文件的目的是爲讓中文讀者更容易閱讀和理解,而不是作爲一個分支。因此, 如果您對此文件有任何意見或改動,請先嘗試更新原始英文文件。如果要更改或 修正某處翻譯文件,請將意見或補丁發送給維護者(聯繫方式見下)。}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hh5Documentation/translations/zh_TW/disclaimer-zh_TW.rsthKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubhnote)}(h如果您發現本文檔與原始文件有任何不同或者有翻譯問題,請聯繫該文件的譯者, 或者發送電子郵件給胡皓文以獲取幫助:<2023002089@link.tyut.edu.cn>。h]h)}(h如果您發現本文檔與原始文件有任何不同或者有翻譯問題,請聯繫該文件的譯者, 或者發送電子郵件給胡皓文以獲取幫助:<2023002089@link.tyut.edu.cn>。h](h如果您發現本文檔與原始文件有任何不同或者有翻譯問題,請聯繫該文件的譯者, 或者發送電子郵件給胡皓文以獲取幫助:<}(hhhhhNhNubh reference)}(h2023002089@link.tyut.edu.cnh]h2023002089@link.tyut.edu.cn}(hhhhhNhNubah}(h]h ]h"]h$]h&]refuri"mailto:2023002089@link.tyut.edu.cnuh1hhhubh>。}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhO/var/lib/git/docbuild/linux/Documentation/translations/zh_TW/dev-tools/gcov.rsthKubh field_body)}(h Documentation/dev-tools/gcov.rsth]h)}(hj h]h Documentation/dev-tools/gcov.rst}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhj ubah}(h]h ]h"]h$]h&]uh1j hhubeh}(h]h ]h"]h$]h&]uh1hhjhKhhhhubh)}(hhh](h)}(h Translatorh]h Translator}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj(hjhKubj )}(h*趙軍奎 Bernard Zhao h]h)}(h)趙軍奎 Bernard Zhao h](h趙軍奎 Bernard Zhao <}(hj=hhhNhNubh)}(hbernard@vivo.comh]hbernard@vivo.com}(hjEhhhNhNubah}(h]h ]h"]h$]h&]refurimailto:bernard@vivo.comuh1hhj=ubh>}(hj=hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhj9ubah}(h]h ]h"]h$]h&]uh1j hj(ubeh}(h]h ]h"]h$]h&]uh1hhjhKhhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhjhKubhsection)}(hhh](htitle)}(h3在Linux內核裏使用gcov做代碼覆蓋率檢查h]h3在Linux內核裏使用gcov做代碼覆蓋率檢查}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1jvhjshhhjhKubh)}(hXkgcov分析核心支持在Linux內核中啓用GCC的覆蓋率測試工具 gcov_ ,Linux內核 運行時的代碼覆蓋率數據會以gcov兼容的格式導出到“gcov”debugfs目錄中,可 以通過gcov的 ``-o`` 選項(如下示例)獲得指定文件的代碼運行覆蓋率統計數據 (需要跳轉到內核編譯路徑下並且要有root權限)::h](hIgcov分析核心支持在Linux內核中啓用GCC的覆蓋率測試工具 }(hjhhhNhNubh)}(hgcov_h]hgcov}(hjhhhNhNubah}(h]h ]h"]h$]h&]namegcovrefuri,https://gcc.gnu.org/onlinedocs/gcc/Gcov.htmluh1hhjresolvedKubh ,Linux內核 運行時的代碼覆蓋率數據會以gcov兼容的格式導出到“gcov”debugfs目錄中,可 以通過gcov的 }(hjhhhNhNubhliteral)}(h``-o``h]h-o}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 選項(如下示例)獲得指定文件的代碼運行覆蓋率統計數據 (需要跳轉到內核編譯路徑下並且要有root權限):}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhK hjshhubh literal_block)}(hT# cd /tmp/linux-out # gcov -o /sys/kernel/debug/gcov/tmp/linux-out/kernel spinlock.ch]hT# cd /tmp/linux-out # gcov -o /sys/kernel/debug/gcov/tmp/linux-out/kernel spinlock.c}hjsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1jhjhKhjshhubh)}(hX這將在當前目錄中創建帶有執行計數註釋的源代碼文件。 在獲得這些統計文件後,可以使用圖形化的gcov前端工具(比如 lcov_ ),來實現 自動化處理Linux內核的覆蓋率運行數據,同時生成易於閱讀的HTML格式文件。h](h這將在當前目錄中創建帶有執行計數註釋的源代碼文件。 在獲得這些統計文件後,可以使用圖形化的gcov前端工具(比如 }(hjhhhNhNubh)}(hlcov_h]hlcov}(hjhhhNhNubah}(h]h ]h"]h$]h&]namelcovj,http://ltp.sourceforge.net/coverage/lcov.phpuh1hhjjKubht ),來實現 自動化處理Linux內核的覆蓋率運行數據,同時生成易於閱讀的HTML格式文件。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjshhubh)}(h可能的用途:h]h可能的用途:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjshhubh bullet_list)}(hhh](h list_item)}(h?調試(用來判斷每一行的代碼是否已經運行過)h]h)}(hj h]h?調試(用來判斷每一行的代碼是否已經運行過)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhj ubah}(h]h ]h"]h$]h&]uh1jhjhhhjhNubj)}(hZ測試改進(如何修改測試代碼,儘可能地覆蓋到沒有運行過的代碼)h]h)}(hj"h]hZ測試改進(如何修改測試代碼,儘可能地覆蓋到沒有運行過的代碼)}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhj ubah}(h]h ]h"]h$]h&]uh1jhjhhhjhNubj)}(h內核最小化配置(對於某一個選項配置,如果關聯的代碼從來沒有運行過, 是否還需要這個配置) h]h)}(h內核最小化配置(對於某一個選項配置,如果關聯的代碼從來沒有運行過, 是否還需要這個配置)h]h內核最小化配置(對於某一個選項配置,如果關聯的代碼從來沒有運行過, 是否還需要這個配置)}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhj7ubah}(h]h ]h"]h$]h&]uh1jhjhhhjhNubeh}(h]h ]h"]h$]h&]bullet*uh1jhjhKhjshhubhtarget)}(h6.. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.htmlh]h}(h]gcovah ]h"]gcovah$]h&]jjuh1jWhK+hjshhhj referencedKubjX)}(h6.. _lcov: http://ltp.sourceforge.net/coverage/lcov.phph]h}(h]lcovah ]h"]lcovah$]h&]jjuh1jWhK,hjshhhjjeKubjr)}(hhh](jw)}(h準備h]h準備}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1jvhjrhhhjhK!ubh)}(h內核打開如下配置::h]h內核打開如下配置:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK#hjrhhubj)}(h&CONFIG_DEBUG_FS=y CONFIG_GCOV_KERNEL=yh]h&CONFIG_DEBUG_FS=y CONFIG_GCOV_KERNEL=y}hjsbah}(h]h ]h"]h$]h&]jjuh1jhjhK%hjrhhubh)}(h8獲取整個內核的覆蓋率數據,還需要打開::h]h7獲取整個內核的覆蓋率數據,還需要打開:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK(hjrhhubj)}(hCONFIG_GCOV_PROFILE_ALL=yh]hCONFIG_GCOV_PROFILE_ALL=y}hjsbah}(h]h ]h"]h$]h&]jjuh1jhjhK*hjrhhubh)}(h需要注意的是,整個內核開啓覆蓋率統計會造成內核鏡像文件尺寸的增大, 同時內核運行也會變慢一些。 另外,並不是所有的架構都支持整個內核開啓覆蓋率統計。h]h需要注意的是,整個內核開啓覆蓋率統計會造成內核鏡像文件尺寸的增大, 同時內核運行也會變慢一些。 另外,並不是所有的架構都支持整個內核開啓覆蓋率統計。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK,hjrhhubh)}(hH代碼運行覆蓋率數據只在debugfs掛載完成後纔可以訪問::h]hG代碼運行覆蓋率數據只在debugfs掛載完成後纔可以訪問:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK0hjrhhubj)}(h'mount -t debugfs none /sys/kernel/debugh]h'mount -t debugfs none /sys/kernel/debug}hjsbah}(h]h ]h"]h$]h&]jjuh1jhjhK2hjrhhubeh}(h]id1ah ]h"]準備ah$]h&]uh1jqhjshhhjhK!ubjr)}(hhh](jw)}(h 定製化h]h 定製化}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jvhjhhhjhK6ubh)}(h如果要單獨針對某一個路徑或者文件進行代碼覆蓋率統計,可以在內核相應路 徑的Makefile中增加如下的配置:h]h如果要單獨針對某一個路徑或者文件進行代碼覆蓋率統計,可以在內核相應路 徑的Makefile中增加如下的配置:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK8hjhhubj)}(hhh](j)}(hI單獨統計單個文件(例如main.o):: GCOV_PROFILE_main.o := y h](h)}(h,單獨統計單個文件(例如main.o)::h]h+單獨統計單個文件(例如main.o):}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK;hjubj)}(hGCOV_PROFILE_main.o := yh]hGCOV_PROFILE_main.o := y}hj!sbah}(h]h ]h"]h$]h&]jjuh1jhjhK=hjubeh}(h]h ]h"]h$]h&]uh1jhj hhhjhNubj)}(h3單獨統計某一個路徑:: GCOV_PROFILE := y h](h)}(h單獨統計某一個路徑::h]h單獨統計某一個路徑:}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK?hj5ubj)}(hGCOV_PROFILE := yh]hGCOV_PROFILE := y}hjGsbah}(h]h ]h"]h$]h&]jjuh1jhjhKAhj5ubeh}(h]h ]h"]h$]h&]uh1jhj hhhjhNubeh}(h]h ]h"]h$]h&]jU-uh1jhjhK;hjhhubh)}(h如果要在整個內核的覆蓋率統計(開啓CONFIG_GCOV_PROFILE_ALL)中單獨排除 某一個文件或者路徑,可以使用如下的方法::h]h如果要在整個內核的覆蓋率統計(開啓CONFIG_GCOV_PROFILE_ALL)中單獨排除 某一個文件或者路徑,可以使用如下的方法:}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKChjhhubj)}(hGCOV_PROFILE_main.o := nh]hGCOV_PROFILE_main.o := n}hjpsbah}(h]h ]h"]h$]h&]jjuh1jhjhKFhjhhubh)}(h和::h]h和:}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKHhjhhubj)}(hGCOV_PROFILE := nh]hGCOV_PROFILE := n}hjsbah}(h]h ]h"]h$]h&]jjuh1jhjhKJhjhhubh)}(hK此機制僅支持鏈接到內核鏡像或編譯爲內核模塊的文件。h]hK此機制僅支持鏈接到內核鏡像或編譯爲內核模塊的文件。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKLhjhhubeh}(h]id2ah ]h"] 定製化ah$]h&]uh1jqhjshhhjhK6ubjr)}(hhh](jw)}(h 相關文件h]h 相關文件}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jvhjhhhjhKPubh)}(h0gcov功能需要在debugfs中創建如下文件:h]h0gcov功能需要在debugfs中創建如下文件:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKRhjhhubhdefinition_list)}(hhh](hdefinition_list_item)}(h8``/sys/kernel/debug/gcov`` gcov相關功能的根路徑 h](hterm)}(h``/sys/kernel/debug/gcov``h]j)}(hjh]h/sys/kernel/debug/gcov}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhjhKUhjubh definition)}(hhh]h)}(hgcov相關功能的根路徑h]hgcov相關功能的根路徑}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKUhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKUhjubj)}(hs``/sys/kernel/debug/gcov/reset`` 全局復位文件:向該文件寫入數據後會將所有的gcov統計數據清0 h](j)}(h ``/sys/kernel/debug/gcov/reset``h]j)}(hjh]h/sys/kernel/debug/gcov/reset}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhjhKXhjubj)}(hhh]h)}(hQ全局復位文件:向該文件寫入數據後會將所有的gcov統計數據清0h]hQ全局復位文件:向該文件寫入數據後會將所有的gcov統計數據清0}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKXhj-ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKXhjhhubj)}(h``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcda`` gcov工具可以識別的覆蓋率統計數據文件,向該文件寫入數據後 會將本文件的gcov統計數據清0 h](j)}(h8``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcda``h]j)}(hjPh]h4/sys/kernel/debug/gcov/path/to/compile/dir/file.gcda}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjNubah}(h]h ]h"]h$]h&]uh1jhjhK\hjJubj)}(hhh]j)}(hhh]j)}(hzgcov工具可以識別的覆蓋率統計數據文件,向該文件寫入數據後 會將本文件的gcov統計數據清0 h](j)}(hRgcov工具可以識別的覆蓋率統計數據文件,向該文件寫入數據後h]hRgcov工具可以識別的覆蓋率統計數據文件,向該文件寫入數據後}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhK\hjkubj)}(hhh]h)}(h&會將本文件的gcov統計數據清0h]h&會將本文件的gcov統計數據清0}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK\hj}ubah}(h]h ]h"]h$]h&]uh1jhjkubeh}(h]h ]h"]h$]h&]uh1jhjhK\hjhubah}(h]h ]h"]h$]h&]uh1jhjeubah}(h]h ]h"]h$]h&]uh1jhjJubeh}(h]h ]h"]h$]h&]uh1jhjhK\hjhhubj)}(h``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcno`` gcov工具需要的軟連接文件(指向編譯時生成的信息統計文件),這個文件是 在gcc編譯時如果配置了選項 ``-ftest-coverage`` 時生成的。 h](j)}(h8``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcno``h]j)}(hjh]h4/sys/kernel/debug/gcov/path/to/compile/dir/file.gcno}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhjhKahjubj)}(hhh]h)}(hgcov工具需要的軟連接文件(指向編譯時生成的信息統計文件),這個文件是 在gcc編譯時如果配置了選項 ``-ftest-coverage`` 時生成的。h](hgcov工具需要的軟連接文件(指向編譯時生成的信息統計文件),這個文件是 在gcc編譯時如果配置了選項 }(hjhhhNhNubj)}(h``-ftest-coverage``h]h-ftest-coverage}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 時生成的。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhK_hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKahjhhubeh}(h]h ]h"]h$]h&]uh1jhjhhhjhNubeh}(h]id3ah ]h"] 相關文件ah$]h&]uh1jqhjshhhjhKPubjr)}(hhh](jw)}(h針對模塊的統計h]h針對模塊的統計}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jvhjhhhjhKdubh)}(hX}內核中的模塊會動態的加載和卸載,模塊卸載時對應的數據會被清除掉。 gcov提供了一種機制,通過保留相關數據的副本來收集這部分卸載模塊的覆蓋率數據。 模塊卸載後這些備份數據在debugfs中會繼續存在。 一旦這個模塊重新加載,模塊關聯的運行統計會被初始化成debugfs中備份的數據。h]hX}內核中的模塊會動態的加載和卸載,模塊卸載時對應的數據會被清除掉。 gcov提供了一種機制,通過保留相關數據的副本來收集這部分卸載模塊的覆蓋率數據。 模塊卸載後這些備份數據在debugfs中會繼續存在。 一旦這個模塊重新加載,模塊關聯的運行統計會被初始化成debugfs中備份的數據。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKfhjhhubh)}(hW可以通過對內核參數gcov_persist的修改來停用gcov對模塊的備份機制::h]hV可以通過對內核參數gcov_persist的修改來停用gcov對模塊的備份機制:}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKkhjhhubj)}(hgcov_persist = 0h]hgcov_persist = 0}hj1sbah}(h]h ]h"]h$]h&]jjuh1jhjhKmhjhhubh)}(h在運行時,用戶還可以通過寫入模塊的數據文件或者寫入gcov復位文件來丟棄已卸 載模塊的數據。h]h在運行時,用戶還可以通過寫入模塊的數據文件或者寫入gcov復位文件來丟棄已卸 載模塊的數據。}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKohjhhubeh}(h]id4ah ]h"]針對模塊的統計ah$]h&]uh1jqhjshhhjhKdubjr)}(hhh](jw)}(h編譯機和測試機分離h]h編譯機和測試機分離}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1jvhjUhhhjhKtubh)}(hXgcov的內核分析插樁支持內核的編譯和運行是在同一臺機器上,也可以編譯和運 行是在不同的機器上。 如果內核編譯和運行是不同的機器,那麼需要額外的準備工作,這取決於gcov工具 是在哪裏使用的:h]hXgcov的內核分析插樁支持內核的編譯和運行是在同一臺機器上,也可以編譯和運 行是在不同的機器上。 如果內核編譯和運行是不同的機器,那麼需要額外的準備工作,這取決於gcov工具 是在哪裏使用的:}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKvhjUhhubjX)}(h.. _gcov-test_zh_TW:h]h}(h]h ]h"]h$]h&]refidgcov-test-zh-twuh1jWhKhjUhhhjubhenumerated_list)}(hhh]j)}(hXa若gcov運行在測試機上 測試機上面gcov工具的版本必須要跟內核編譯機器使用的gcc版本相兼容, 同時下面的文件要從編譯機拷貝到測試機上: 從源代碼中: - 所有的C文件和頭文件 從編譯目錄中: - 所有的C文件和頭文件 - 所有的.gcda文件和.gcno文件 - 所有目錄的鏈接 特別需要注意,測試機器上面的目錄結構跟編譯機器上面的目錄機構必須 完全一致。 如果文件是軟鏈接,需要替換成真正的目錄文件(這是由make的當前工作 目錄變量CURDIR引起的)。 h](h)}(h若gcov運行在測試機上h]h若gcov運行在測試機上}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK}hjubh block_quote)}(hX7測試機上面gcov工具的版本必須要跟內核編譯機器使用的gcc版本相兼容, 同時下面的文件要從編譯機拷貝到測試機上: 從源代碼中: - 所有的C文件和頭文件 從編譯目錄中: - 所有的C文件和頭文件 - 所有的.gcda文件和.gcno文件 - 所有目錄的鏈接 特別需要注意,測試機器上面的目錄結構跟編譯機器上面的目錄機構必須 完全一致。 如果文件是軟鏈接,需要替換成真正的目錄文件(這是由make的當前工作 目錄變量CURDIR引起的)。 h](h)}(h測試機上面gcov工具的版本必須要跟內核編譯機器使用的gcc版本相兼容, 同時下面的文件要從編譯機拷貝到測試機上:h]h測試機上面gcov工具的版本必須要跟內核編譯機器使用的gcc版本相兼容, 同時下面的文件要從編譯機拷貝到測試機上:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubj)}(hhh](j)}(h0從源代碼中: - 所有的C文件和頭文件 h](j)}(h從源代碼中:h]h從源代碼中:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhKhjubj)}(hhh]j)}(hhh]j)}(h所有的C文件和頭文件 h]h)}(h所有的C文件和頭文件h]h所有的C文件和頭文件}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]jUjauh1jhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKhjubj)}(hp從編譯目錄中: - 所有的C文件和頭文件 - 所有的.gcda文件和.gcno文件 - 所有目錄的鏈接 h](j)}(h從編譯目錄中:h]h從編譯目錄中:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhKhjubj)}(hhh]j)}(hhh](j)}(h所有的C文件和頭文件h]h)}(hj h]h所有的C文件和頭文件}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(h"所有的.gcda文件和.gcno文件h]h)}(hj!h]h"所有的.gcda文件和.gcno文件}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(h所有目錄的鏈接 h]h)}(h所有目錄的鏈接h]h所有目錄的鏈接}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhj6ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]jUjauh1jhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKhjubeh}(h]h ]h"]h$]h&]uh1jhjubh)}(h特別需要注意,測試機器上面的目錄結構跟編譯機器上面的目錄機構必須 完全一致。 如果文件是軟鏈接,需要替換成真正的目錄文件(這是由make的當前工作 目錄變量CURDIR引起的)。h]h特別需要注意,測試機器上面的目錄結構跟編譯機器上面的目錄機構必須 完全一致。 如果文件是軟鏈接,需要替換成真正的目錄文件(這是由make的當前工作 目錄變量CURDIR引起的)。}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubeh}(h]h ]h"]h$]h&]uh1jhjhKhjubeh}(h]h ]h"]h$]h&]uh1jhjhhhjhNubah}(h]jah ]h"]gcov-test_zh_twah$]h&]enumtype loweralphaprefixhsuffix)uh1jhjUhhhjhK}expect_referenced_by_name}jjtsexpect_referenced_by_id}jjtsubjX)}(h.. _gcov-build_zh_TW:h]h}(h]h ]h"]h$]h&]j~gcov-build-zh-twuh1jWhKhjUhhhjubj)}(hhh]j)}(hXj若gcov運行在編譯機上 測試用例運行結束後,如下的文件需要從測試機中拷貝到編譯機上: 從sysfs中的gcov目錄中: - 所有的.gcda文件 - 所有的.gcno文件軟鏈接 這些文件可以拷貝到編譯機的任意目錄下,gcov使用-o選項指定拷貝的 目錄。 比如一個是示例的目錄結構如下:: /tmp/linux: 內核源碼目錄 /tmp/out: 內核編譯文件路徑(make O=指定) /tmp/coverage: 從測試機器上面拷貝的數據文件路徑 [user@build] cd /tmp/out [user@build] gcov -o /tmp/coverage/tmp/out/init main.c h](h)}(h若gcov運行在編譯機上h]h若gcov運行在編譯機上}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubj)}(hX@測試用例運行結束後,如下的文件需要從測試機中拷貝到編譯機上: 從sysfs中的gcov目錄中: - 所有的.gcda文件 - 所有的.gcno文件軟鏈接 這些文件可以拷貝到編譯機的任意目錄下,gcov使用-o選項指定拷貝的 目錄。 比如一個是示例的目錄結構如下:: /tmp/linux: 內核源碼目錄 /tmp/out: 內核編譯文件路徑(make O=指定) /tmp/coverage: 從測試機器上面拷貝的數據文件路徑 [user@build] cd /tmp/out [user@build] gcov -o /tmp/coverage/tmp/out/init main.c h](h)}(hX測試用例運行結束後,如下的文件需要從測試機中拷貝到編譯機上:h]hX測試用例運行結束後,如下的文件需要從測試機中拷貝到編譯機上:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubj)}(hhh]j)}(hT從sysfs中的gcov目錄中: - 所有的.gcda文件 - 所有的.gcno文件軟鏈接 h](j)}(h從sysfs中的gcov目錄中:h]h從sysfs中的gcov目錄中:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhKhjubj)}(hhh]j)}(hhh](j)}(h所有的.gcda文件h]h)}(hjh]h所有的.gcda文件}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(h所有的.gcno文件軟鏈接 h]h)}(h所有的.gcno文件軟鏈接h]h所有的.gcno文件軟鏈接}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]jUjauh1jhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubh)}(hd這些文件可以拷貝到編譯機的任意目錄下,gcov使用-o選項指定拷貝的 目錄。h]hd這些文件可以拷貝到編譯機的任意目錄下,gcov使用-o選項指定拷貝的 目錄。}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubh)}(h,比如一個是示例的目錄結構如下::h]h+比如一個是示例的目錄結構如下:}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubj)}(h/tmp/linux: 內核源碼目錄 /tmp/out: 內核編譯文件路徑(make O=指定) /tmp/coverage: 從測試機器上面拷貝的數據文件路徑 [user@build] cd /tmp/out [user@build] gcov -o /tmp/coverage/tmp/out/init main.ch]h/tmp/linux: 內核源碼目錄 /tmp/out: 內核編譯文件路徑(make O=指定) /tmp/coverage: 從測試機器上面拷貝的數據文件路徑 [user@build] cd /tmp/out [user@build] gcov -o /tmp/coverage/tmp/out/init main.c}hj@sbah}(h]h ]h"]h$]h&]jjuh1jhjhKhjubeh}(h]h ]h"]h$]h&]uh1jhjhKhjubeh}(h]h ]h"]h$]h&]uh1jhjhhhjhNubah}(h]jah ]h"]gcov-build_zh_twah$]h&]jjjhjjstartKuh1jhjUhhhjhKj}j^jsj}jjsubeh}(h]id5ah ]h"]編譯機和測試機分離ah$]h&]uh1jqhjshhhjhKtubjr)}(hhh](jw)}(h關於編譯器的注意事項h]h關於編譯器的注意事項}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1jvhjlhhhjhKubh)}(hGCC和LLVM gcov工具不一定兼容。 如果編譯器是GCC,使用 gcov_ 來處理.gcno和.gcda文件,如果是Clang編譯器, 則使用 llvm-cov_ 。h](hGGCC和LLVM gcov工具不一定兼容。 如果編譯器是GCC,使用 }(hj}hhhNhNubh)}(hgcov_h]hgcov}(hjhhhNhNubah}(h]h ]h"]h$]h&]namegcovjjuh1hhj}jKubhE 來處理.gcno和.gcda文件,如果是Clang編譯器, 則使用 }(hj}hhhNhNubh)}(h llvm-cov_h]hllvm-cov}(hjhhhNhNubah}(h]h ]h"]h$]h&]namellvm-covj0https://llvm.org/docs/CommandGuide/llvm-cov.htmluh1hhj}jKubh 。}(hj}hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjlhhubjX)}(h6.. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.htmlh]h}(h]id7ah ]h"]h$]gcovah&]j,https://gcc.gnu.org/onlinedocs/gcc/Gcov.htmluh1jWhKjeKhjlhhhjubjX)}(h>.. _llvm-cov: https://llvm.org/docs/CommandGuide/llvm-cov.htmlh]h}(h]llvm-covah ]h"]llvm-covah$]h&]jjuh1jWhKhjlhhhjjeKubh)}(hGCC和Clang gcov之間的版本差異由Kconfig處理的。 kconfig會根據編譯工具鏈的檢查自動選擇合適的gcov格式。h]hGCC和Clang gcov之間的版本差異由Kconfig處理的。 kconfig會根據編譯工具鏈的檢查自動選擇合適的gcov格式。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjlhhubeh}(h]id6ah ]h"]關於編譯器的注意事項ah$]h&]uh1jqhjshhhjhKubjr)}(hhh](jw)}(h 問題定位h]h 問題定位}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jvhjhhhjhKubj)}(hhh](j)}(h9可能出現的問題1 編譯到鏈接階段報錯終止 h](j)}(h可能出現的問題1h]h可能出現的問題1}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhKhjubj)}(hhh]h)}(h!編譯到鏈接階段報錯終止h]h!編譯到鏈接階段報錯終止}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhj ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKhjubj)}(hn問題原因 分析標誌指定在了源文件但是沒有鏈接到主內核,或者客製化了鏈接程序 h](j)}(h 問題原因h]h 問題原因}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhKhj&ubj)}(hhh]h)}(h`分析標誌指定在了源文件但是沒有鏈接到主內核,或者客製化了鏈接程序h]h`分析標誌指定在了源文件但是沒有鏈接到主內核,或者客製化了鏈接程序}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhj8ubah}(h]h ]h"]h$]h&]uh1jhj&ubeh}(h]h ]h"]h$]h&]uh1jhjhKhjhhubj)}(h解決方法 通過在相應的Makefile中使用 ``GCOV_PROFILE := n`` 或者 ``GCOV_PROFILE_basename.o := n`` 來將鏈接報錯的文件排除掉 h](j)}(h 解決方法h]h 解決方法}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhKhjUubj)}(hhh]h)}(h通過在相應的Makefile中使用 ``GCOV_PROFILE := n`` 或者 ``GCOV_PROFILE_basename.o := n`` 來將鏈接報錯的文件排除掉h](h$通過在相應的Makefile中使用 }(hjjhhhNhNubj)}(h``GCOV_PROFILE := n``h]hGCOV_PROFILE := n}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjjubh 或者 }(hjjhhhNhNubj)}(h ``GCOV_PROFILE_basename.o := n``h]hGCOV_PROFILE_basename.o := n}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjjubh% 來將鏈接報錯的文件排除掉}(hjjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjgubah}(h]h ]h"]h$]h&]uh1jhjUubeh}(h]h ]h"]h$]h&]uh1jhjhKhjhhubj)}(hG可能出現的問題2 從sysfs複製的文件顯示爲空或不完整 h](j)}(h可能出現的問題2h]h可能出現的問題2}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhKhjubj)}(hhh]h)}(h/從sysfs複製的文件顯示爲空或不完整h]h/從sysfs複製的文件顯示爲空或不完整}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKhjhhubj)}(h{問題原因 由於seq_file的工作方式,某些工具(例如cp或tar)可能無法正確地從 sysfs複製文件。 h](j)}(h 問題原因h]h 問題原因}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhKhjubj)}(hhh]h)}(hm由於seq_file的工作方式,某些工具(例如cp或tar)可能無法正確地從 sysfs複製文件。h]hm由於seq_file的工作方式,某些工具(例如cp或tar)可能無法正確地從 sysfs複製文件。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKhjhhubj)}(h解決方法 使用 ``cat`` 讀取 ``.gcda`` 文件,使用 ``cp -d`` 複製鏈接,或者使用附錄B 中所示的機制。 h](j)}(h 解決方法h]h 解決方法}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhKhj ubj)}(hhh]h)}(hr使用 ``cat`` 讀取 ``.gcda`` 文件,使用 ``cp -d`` 複製鏈接,或者使用附錄B 中所示的機制。h](h使用 }(hj hhhNhNubj)}(h``cat``h]hcat}(hj# hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 讀取 }(hj hhhNhNubj)}(h ``.gcda``h]h.gcda}(hj5 hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 文件,使用 }(hj hhhNhNubj)}(h ``cp -d``h]hcp -d}(hjG hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh9 複製鏈接,或者使用附錄B 中所示的機制。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhjhKhjhhubeh}(h]h ]h"]h$]h&]uh1jhjhhhjhNubeh}(h]id8ah ]h"] 問題定位ah$]h&]uh1jqhjshhhjhKubjr)}(hhh](jw)}(h附錄A:collect_on_build.shh]h附錄A:collect_on_build.sh}(hj| hhhNhNubah}(h]h ]h"]h$]h&]uh1jvhjy hhhjhKubh)}(h用於在編譯機上收集覆蓋率元文件的示例腳本 (見 :ref:`編譯機和測試機分離 a. ` )h](hD用於在編譯機上收集覆蓋率元文件的示例腳本 (見 }(hj hhhNhNubh)}(h7:ref:`編譯機和測試機分離 a. `h]hinline)}(hj h]h編譯機和測試機分離 a.}(hj hhhNhNubah}(h]h ](xrefstdstd-refeh"]h$]h&]uh1j hj ubah}(h]h ]h"]h$]h&]refdoc!translations/zh_TW/dev-tools/gcov refdomainj reftyperef refexplicitrefwarn reftargetgcov-test_zh_twuh1hhjhKhj ubh )}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjy hhubj)}(hXg#!/bin/bash KSRC=$1 KOBJ=$2 DEST=$3 if [ -z "$KSRC" ] || [ -z "$KOBJ" ] || [ -z "$DEST" ]; then echo "Usage: $0 " >&2 exit 1 fi KSRC=$(cd $KSRC; printf "all:\n\t@echo \${CURDIR}\n" | make -f -) KOBJ=$(cd $KOBJ; printf "all:\n\t@echo \${CURDIR}\n" | make -f -) find $KSRC $KOBJ \( -name '*.gcno' -o -name '*.[ch]' -o -type l \) -a \ -perm /u+r,g+r | tar cfz $DEST -P -T - if [ $? -eq 0 ] ; then echo "$DEST successfully created, copy to test system and unpack with:" echo " tar xfz $DEST -P" else echo "Could not create file $DEST" fih]hXg#!/bin/bash KSRC=$1 KOBJ=$2 DEST=$3 if [ -z "$KSRC" ] || [ -z "$KOBJ" ] || [ -z "$DEST" ]; then echo "Usage: $0 " >&2 exit 1 fi KSRC=$(cd $KSRC; printf "all:\n\t@echo \${CURDIR}\n" | make -f -) KOBJ=$(cd $KOBJ; printf "all:\n\t@echo \${CURDIR}\n" | make -f -) find $KSRC $KOBJ \( -name '*.gcno' -o -name '*.[ch]' -o -type l \) -a \ -perm /u+r,g+r | tar cfz $DEST -P -T - if [ $? -eq 0 ] ; then echo "$DEST successfully created, copy to test system and unpack with:" echo " tar xfz $DEST -P" else echo "Could not create file $DEST" fi}hj sbah}(h]h ]h"]h$]h&]jjforcelanguageshhighlight_args}uh1jhjhKhjy hhubeh}(h]a-collect-on-build-shah ]h"]附錄a:collect_on_build.shah$]h&]uh1jqhjshhhjhKubjr)}(hhh](jw)}(h附錄B:collect_on_test.shh]h附錄B:collect_on_test.sh}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jvhj hhhjhKubh)}(h用於在測試機上收集覆蓋率數據文件的示例腳本 (見 :ref:`編譯機和測試機分離 b. ` )h](hG用於在測試機上收集覆蓋率數據文件的示例腳本 (見 }(hj hhhNhNubh)}(h8:ref:`編譯機和測試機分離 b. `h]j )}(hj h]h編譯機和測試機分離 b.}(hj hhhNhNubah}(h]h ](j stdstd-refeh"]h$]h&]uh1j hj ubah}(h]h ]h"]h$]h&]refdocj refdomainj reftyperef refexplicitrefwarnj gcov-build_zh_twuh1hhjhKhj ubh )}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhj hhubj)}(hX#!/bin/bash -e DEST=$1 GCDA=/sys/kernel/debug/gcov if [ -z "$DEST" ] ; then echo "Usage: $0 " >&2 exit 1 fi TEMPDIR=$(mktemp -d) echo Collecting data.. find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \; find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \; find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \; tar czf $DEST -C $TEMPDIR sys rm -rf $TEMPDIR echo "$DEST successfully created, copy to build system and unpack with:" echo " tar xfz $DEST"h]hX#!/bin/bash -e DEST=$1 GCDA=/sys/kernel/debug/gcov if [ -z "$DEST" ] ; then echo "Usage: $0 " >&2 exit 1 fi TEMPDIR=$(mktemp -d) echo Collecting data.. find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \; find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \; find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \; tar czf $DEST -C $TEMPDIR sys rm -rf $TEMPDIR echo "$DEST successfully created, copy to build system and unpack with:" echo " tar xfz $DEST"}hj sbah}(h]h ]h"]h$]h&]jjj j shj }uh1jhjhKhj hhubeh}(h]b-collect-on-test-shah ]h"]附錄b:collect_on_test.shah$]h&]uh1jqhjshhhjhKubeh}(h] linuxgcovah ]h"]3在linux內核裏使用gcov做代碼覆蓋率檢查ah$]h&]uh1jqhhhhhjhKubeh}(h]h ]h"]h$]h&]sourcejuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(jvN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjb error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourcej _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}(gcov](jjelcov]jallvm-cov]jaurefids}(j]jtaj]jaunameids}(j< j9 jbj_jojljjjjjjjRjOjijfjjj^jjjjjjv js j j j4 j1 u nametypes}(j< jbjojjjjRjijj^jjjv j j4 uh}(j9 jsj_jYjljfjjrjjjjjOjjfjUjjjjjjljjjjjs jj jy j1 j u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jp KsRparse_messages](hsystem_message)}(hhh]h)}(h:Enumerated list start value not ordinal-1: "b" (ordinal 2)h]h>Enumerated list start value not ordinal-1: “b” (ordinal 2)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcejlineKuh1j hjUhhhjhKubj )}(hhh]h)}(h'Duplicate explicit target name: "gcov".h]h+Duplicate explicit target name: “gcov”.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]jalevelKtypej lineKsourcejuh1j hjlhhhjhKubetransform_messages](j )}(hhh]h)}(hhh]h5Hyperlink target "gcov-test-zh-tw" is not referenced.}hj sbah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]levelKtypej sourcejlineKuh1j ubj )}(hhh]h)}(hhh]h6Hyperlink target "gcov-build-zh-tw" is not referenced.}hj$ sbah}(h]h ]h"]h$]h&]uh1hhj! ubah}(h]h ]h"]h$]h&]levelKtypej sourcejlineKuh1j ube transformerN include_log]3Documentation/translations/zh_TW/dev-tools/gcov.rst(NNNNta decorationNhhub.