XCode Coverage Data 為0 的解決歷程

筆者最近在做單元測試框架的搭建璧南,做到輸出代碼覆蓋率的時候掌逛,發(fā)現app的代碼覆蓋率一直是0,然后就開啟了歷程一周的找碴過程司倚,其中嫌棄電腦太慢豆混,直接花了1w4買入了新的macbook pro(M1 pro)篓像,不得不說,生產力杠杠的皿伺,不過現在系統有個問題會造成播放音樂時出現噗噗的聲音有點煩人员辩。

好,進入主題:

問題描述:
如圖鸵鸥,跑完單元測試后XCode Coverage Report 顯示為零奠滑。Log顯示提示語是:
Failed to generate coverage for target 'XXX.app' at paths (xxxxxxx): Failed to decompress coverage data (zlib)


image.png

但是,Test target還是有報告出來的妒穴。
為此宋税,筆者幾乎搜遍了google baidu bing,沒有一個相同的問題讼油,我想我遇到了所有人都沒有遇到過的棘手的問題弃甥。

·初步思考
1、工程比較復雜汁讼,可能沒法正常輸出結果
2、XCode可能有bug阔墩,就是沒法輸出結果
3嘿架、工程有問題,沒法正常輸出結果

·并嘗試解決:
1啸箫、通過新建一個空的工程耸彪,并跑一次單元測試,正常輸出忘苛。
2蝉娜、新工程引入一個原工程的文件,并把各種庫鏈接完成扎唾,跑一次單元測試召川,并重復幾次操作,發(fā)現胸遇,當庫文件還比較少時荧呐,還是可以輸出測試報告,但一旦庫引用接近原工程時纸镊,報告就無法生成了倍阐。
最后,初步定性為3逗威,工程有問題峰搪,結合網上壓根沒有相關的資料,就比較肯定了凯旭,畢竟筆者的工程結構是真的過于復雜概耻。

·嘗試細致定位問題:
工程有問題使套,可能是其中某個庫導致的。著手嘗試逐個庫引入并進行單元測試咐蚯,最終發(fā)現引入libprotobuf時童漩,同時other linker flag 設為-ObjC時,會出現該問題春锋。-ObjC標記是鏈接時矫膨,會將所有靜態(tài)庫中的Objective C class和category加載到包中。那估計就是libprotobuf中的東西引進去導致了問題期奔。
試圖繞開libprotobuf侧馅,通過force_load逐個將需要的包加載,結果呐萌,失敗馁痴。

來到這里,人都崩潰了肺孤,搞了大半天罗晕,回到原點,可能并不是單單libprotobuf的問題赠堵,有可能是加載Objective C category的問題小渊。

·高階嘗試:
繞開不行,那我換一種單元測試方案茫叭,不用XCode輸出報告了酬屉,直接走精準測試的方案,畢竟XCode是個黑盒揍愁,查了那么多資料至今也不知道XCode的覆蓋率報告用的是哪個方案(后來知道了)呐萨。
1、llvm gcov方案 莽囤,通過.gcda .gcno的方案谬擦,但是無法檢測swift的代碼
2、llvm Source-Based Code Coverage方案烁登,通過生成.profraw .profdata怯屉,比較完整的方案,而且精測基本上走得這個方案饵沧,可行性高锨络,社區(qū)信息豐富。
3狼牺、SanitizerCoverage羡儿,另一種插樁方式,幾乎沒人用來做覆蓋率報告是钥,難度高

經過實施掠归,
第1方案是可行的缅叠,但是無法生成swift的代碼
第2方案,歷經千辛萬苦虏冻,最后工具報錯 Failed to decompress coverage data (zlib)肤粱。

崩潰了。厨相。领曼。

可以看出,其實XCode的單元測試代碼覆蓋率報告是用llvm Source-Based Code Coverage的方案進行的蛮穿,只是最后在.profdata輸出的基礎上進行ui層面的加工庶骄,我們也可以在編譯中間文件中找到Coverage.profdata。

第3方案践磅,是一個大工程单刁,根本不可能短時間完成,但是幾乎可以肯定府适,報告肯定可以做出來的羔飞。

·lvm-cov Source-Based Code Coverage方案Deep Dive:
無論通過自己走llvm SourceBaseCodeCoverage方案生成的profdata,還是xcode收集的profdata檐春,在llvm-cov工具執(zhí)行 show的時候褥傍,都會報同樣的錯誤 Failed to decompress coverage data (zlib)。
只能迎難而上喇聊,找出問題的根本原因了。也就是工程為什么會導致該搞錯蹦狂。

1誓篱、下載LLVM Project:
2、執(zhí)行 All_Build target凯楔,完整編譯一次llvm
3窜骄、找到llvm-cov工具文件,閱讀源碼摆屯,并進行Debug
4邻遏、使用xcode生成的profdata,執(zhí)行l(wèi)lvm-cov show命令虐骑,并進行斷點研究

有幾個發(fā)現准验,
1、zlib其實是對二進制碼進行解壓的工具廷没,llvm執(zhí)行編譯時糊饱,是通過對代碼插樁,從而收集代碼執(zhí)行的情況颠黎。.profdata應該是執(zhí)行的Log另锋。llvm-cov show是通過zlib解壓二進制包和代碼滞项,關聯.profdata,最終整合出報告夭坪。
2文判、llvm-cov show時崩潰,觸發(fā)了CoverageMappingReader.cpp中的assert((CovMapVersion)CovHeader->getVersion<Endian>() == Version)室梅。原因是getVersion = 2, Version = 4 戏仓。
3、注釋掉該行assert代碼竞惋,程序跑完后報錯 Failed to decompress coverage data (zlib)柜去。

問題關鍵點找到了!

但是拆宛,為什么呢嗓奢?

繼續(xù)對llvm-cov show執(zhí)行過程進行debug,發(fā)現浑厚,其實zlib解析了大部分代碼都是正常的股耽,但是一到某個地方就version對不上,上下文也無法定位钳幅,因為解析的信息出來是空的物蝙。
經過對代碼繼續(xù)排查,試圖找到哪個包出現問題敢艰,最后發(fā)現诬乞,還是執(zhí)行到解析libprotobuf相關代碼出現問題。

醉了钠导,最終還是libprotobuf的問題震嫉,反思了一下,之前force_load時為什么還是不行牡属?而且票堵,libprotobuf的代碼不應該在里面,因為其他靜態(tài)庫文件都是沒有在里面的逮栅,libprotobuf應該沒有插樁的啊悴势,怎么會收集上來呢。

重新拉protobuf工程措伐,編一個iOS的lib特纤,替換,執(zhí)行單測侥加。
結果叫潦,報告出來了,醉了醉了〈H铮肯定是原來的包混進了奇怪的東西短蜕。(后面對比了一下,好像也沒什么問題傻咖,確實protobuf的.m會被插樁朋魔,protobuf-iOS的編譯跟普通的庫還是不一樣,難道是版本編譯出的問題卿操?對于llvm還是不熟警检,最終原因還有待確定)

總結:
本次問題還是很棘手的,每一步都沒有參考的方法和思路害淤。由于xcode是黑盒扇雕,不知道用的哪種代碼覆蓋收集方案導致一開始就沒有走正確的路線。其次窥摄,一提到llvm覺得是很難的東西镶奉,沒有靜下心來細看。最后崭放,還是因為知識匱乏哨苛,導致彎路走了很多。經此一戰(zhàn)币砂,以后llvm工具報錯出問題都不用擔心了建峭。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市决摧,隨后出現的幾起案子亿蒸,更是在濱河造成了極大的恐慌,老刑警劉巖掌桩,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祝懂,死亡現場離奇詭異,居然都是意外死亡拘鞋,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門矢门,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盆色,“玉大人,你說我怎么就攤上這事祟剔「舳悖” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵物延,是天一觀的道長宣旱。 經常有香客問我,道長叛薯,這世上最難降的妖魔是什么浑吟? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任笙纤,我火速辦了婚禮,結果婚禮上组力,老公的妹妹穿的比我還像新娘省容。我一直安慰自己,他們只是感情好燎字,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布腥椒。 她就那樣靜靜地躺著,像睡著了一般候衍。 火紅的嫁衣襯著肌膚如雪笼蛛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天蛉鹿,我揣著相機與錄音滨砍,去河邊找鬼。 笑死榨为,一個胖子當著我的面吹牛惨好,可吹牛的內容都是我干的。 我是一名探鬼主播随闺,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼日川,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了矩乐?” 一聲冷哼從身側響起龄句,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎散罕,沒想到半個月后分歇,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡欧漱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年职抡,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片误甚。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡缚甩,死狀恐怖,靈堂內的尸體忽然破棺而出窑邦,到底是詐尸還是另有隱情擅威,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布冈钦,位于F島的核電站郊丛,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜厉熟,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一导盅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧庆猫,春花似錦认轨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至杉畜,卻和暖如春纪蜒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背此叠。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工纯续, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人灭袁。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓猬错,卻偏偏與公主長得像,于是被迫代替她去往敵國和親茸歧。 傳聞我的和親對象是個殘疾皇子倦炒,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內容