硬核:嵌入式代码覆盖率统计方法和经验

嵌入式ARM 2021-01-05 00:00


代码覆盖率是衡量软件测试完成情况的指标,通常基于测试过程中已检查的程序源代码比例计算得出。代码覆盖率可以有效避免包含未测试代码的程序被发布。


1. 问题背景


代码覆盖(Code coverage)是软件测试中的一种度量,描述程式中源代码被测试的比例和程度,所得比例称为代码覆盖率。

在进行代码测试时,常常使用代码覆盖率作为考核测试任务完整性的指标,并且代码覆盖率也被拿来作为衡量代码质量的度量,甚至客户常常要求交付的软件达到一定的代码覆盖率才能进行发布,因此代码覆盖率统计尤为重要。

C语言嵌入式软件的开发与普通的软件的开发很大的不同点就是需要采用交叉开发的方式,即开发工具运行在软硬件配置丰富的编译机上,而嵌入式应用程序则运行在软硬件资源相对缺乏的目标机上。面对C语言的覆盖率工具相对java等语言较少,而对嵌入式软件交叉编译后的工具更是凤毛麟角,所以嵌入式软件的代码覆盖率就成为了一个难题。

2. 解决方法


2.1 覆盖率工具


嵌入式开发一般使用GNU/GCC作为主要的编译器,GCOV是一个GNU/GCC的配套测试覆盖率的工具,是一款的免费的代码覆盖率测试工具,而且可以结合LCOV生成美观的html的测试报表。当对目标代码进行测试后,GCOV编译插桩后的程序会监视目标代码的执行情况,记录执行的代码行和未执行的代码行,并可以记录某代码行的执行次数,为分析代码的执行效率提供依据。

LCOV是GCOV的一个扩展工具,该扩展工具由一套Perl脚本组成,使基于GCOV的文本式输出实现了一下的增强的功能:

1.基于html的输出,使用条形图和不同的颜色来表。

2.支持大型项目,信息汇总页面提供三个层次的代码覆盖细节信息,目录试图、文件试图和源代码试图,允许快速浏览代码覆盖率数据。


2.2 原理简介

2.2.1 概念解释

下面对覆盖率技术的常见概念进行简单介绍。主要是基本块(Basic Block),基本块图(Basic Block Graph),行覆盖率(line coverage), 分支覆盖率(branch coverage)等。

基本块(Basic Block),"A basic block is asequence of instructions with only entry and only one exit. If any one of theinstructions are executed, they will all be executed, and in sequence fromfirst to last."  这里可以把基本块看成一行整体的代码,基本块内的代码是线性的,要不全部运行,要不都不运行。

基本块图(Basic Block Graph),基本块的最后一条语句一般都要跳转,否则后面一条语句也会被计算为基本块的一部分。如果跳转语句是有条件的,就产生了一个分支(arc),该基本块就有两个基本块作为目的地。如果把每个基本块当作一个节点,那么一个函数中的所有基本块就构成了一个有向图,称之为基本块图(Basic Block Graph)。且只要知道图中部分BB或arc的执行次数就可以推算出所有的BB和所有的arc的执行次数。

图1 基本块图


打桩,意思是在有效的基本块之间增加计数器,计算该基本块被运行的次数;打桩的位置都是在基本块图的有效边上。

行覆盖率(line coverage),源代码有效行数与被执行的代码行的比率。

分支覆盖率(branch coverage),有判定语句的地方都会出现2个分支,整个程序经过的分支与所有分支的比率是分支覆盖率。注意,与条件覆盖率(condition coverage)有细微差别,条件覆盖率在判定语句的组合上有更细的划分。
 
2.2.2 编译选项

gcc需要静态注入目标程序编译选项,在编译链接的时候加入2个选项(-ftest-coverage -fprofile-arcs ),编译结束之后会生成 gcno文件,而经过静态注入的目标程序在“正常结束”后,会在运行目录下产生gcda数据文件,通过gcov工具就可产生覆盖率数据结果。

-ftest-coverage

让编译器生成与源代码同名的gcno文件(note file),这种文件含有重建基本块依赖图和将源代码关联至基本块及源代码行号的必要信息。

-fprofile-arcs

让编译器静态注入对每个源代码行关联的计数器进行操作的代码,并在链接阶段链入经态度libgcov.a,其中包含在程序正常结束时生成gcda文件的逻辑和记录弧跳变的次数及其他的概要信息。

在最终可执行程序进入用户代码入口函数之前调用 gcov_init()内部函数初始化统计数据区,并将gcov_exit()内部函数注册为代码出口。

当程序调用代码出口正常结束时,gcov_exit()内部函数得到调用,其继续调用__gcov_flush()内部函数输出统计数据并生成gcda文件,若程序是一个状态机程序不会自动调用代码出口时,需要增加定时器等方式调用__gcov_flush()内部函数强制输出gcda文件。

2.3 实践应用


利用GCOV和LCOV工具可以进行嵌入式代码覆盖率的统计,需要在Makefile或者Scons文件中做下面的编译链接设置,增加 -fprofile-arcs -ftest-coverage 或者 –coverage,链接的时候,增加 -fprofile-arcs 或者 –lgcov。

为了上述几个编译选项的使用不影响到正常的编译过程和效率。可以使用makefile中通过参数传递来支持覆盖率产生,可以在makefile使用下面的方式:

#代码覆盖率编译选项
ifeq (_CODE_COV,$(CODE))APP_FLAGS += -fprofile-arcs -ftest-coverageendif

#代码覆盖率链接选项
ifeq (_CODE_COV,$(CODE))LD_LINK_LIBFILTER += -fprofile-arcs -ftest-coverageendif

这样,可以使用 make CODE=_CODE_COV 来引入这些编译选项而不会影响到正常的编译。

将目标机生成的gcda文件放回至编译目录下,利用LCOV命令“lcov –directory. –capture –output file app.info”可以将gcno文件和gcda文件结合生成代码覆盖率结果info文件,再用LCOV命令“genhtml –o html app.info –title “LCOV–app.Info” –show-details -legend”将info文件和源代码文件结合转化为可视化网页形式。


图2 LCOV生成HTML结果


3. 高手总结方法


代码覆盖率等级

代码覆盖率可以通过多种方法测量。最常用的是测量以下一个或多个指标:语句覆盖率,分支 覆盖率,修订的条件/判定覆盖率(MC/DC)。以下章节中将逐一详解这些代码覆盖率。


语句覆盖率

语句覆盖率用来度量被测代码中的可执行语句是否被执行到,它并不考虑循环或者条件语句, 只针对语句度量可执行代码。应当特别注意的是:“语句”并不等同于代码行。


一般情况下,对于 C,C++,Java或Ada,分号代表语句结束。在某些情况下,一条语句会跨越多行代码。语句覆盖率可以有效度量可执行代码是否被执行,但同时也有一定的局限性。


语句覆盖率的局限

考虑如下图1的代码段:

int* p = NULL;

if (condition)

p = &variable;

*p = 123;

图 1 – 语句覆盖局限代码示例

如果“condition”为true,那么就有可能达到100%的语句覆盖,然而这个测试用例忽略了另一种情况:如果“condition”为假,程序将引用空指针,因此,虽然语句覆盖率是一个很好的度量指标,它仍旧是入门级的代码覆盖率。理想情况下,即使“condition”为false,测试用例也应当被计算。


分支覆盖率

分支覆盖率用来度量程序中所有的判定和分支以及相应的输出是否都被测试执行到,例如 “if”语句必须将“true”和“false”都考虑到以覆盖所有的输出。如果只有一个路径被执行,那么覆盖率将被标记为部分执行。


和语句覆盖率类似,分支覆盖浪费也有一些需要注意的细节,尤其在针对“惰性求值”的编程语言时,惰性求值是将代码的求值操作延迟到需要结果值时再进行的一项技术。


分支覆盖率的局限

典型的情况是当有复杂的布尔表达式的“惰性求值”出现时,如下图2的代码片段:


int* p = NULL;if (condition1 && (condition2 || function1(*p)))statement1;else


考虑“condition1”为假的情况,惰性求值将不会度量“condition2”或,此种情况同样会导致代码“if (condition1 && (condition2 || function1(*p)))”的分支覆盖率计算错误。


继续考虑“condition1”和“condition2”都为真的情况。惰性求值将再次导致“function1(*p)” 不会被度量,也同样会导致代码“if (condition1 && (condition2 || function1(*p)))”的分支覆盖率计算错误。在此种情况下,有可能出现分支覆盖率为100%但软件中仍有潜在缺陷的情况。


修订条件/判定覆盖率(MC/DC)

MC/DC是一种特殊的分支覆盖率,它不但会使用分支覆盖率报告复杂条件下的true和false输出,同时也会报告复杂条件下的全部分支条件输出。


MC/DC最初由波音公司创建,用于航空软件中DO-178B的A级认证。通过对所有的子条件输出分支的独立证明,有效解决了惰性求值带来的问题。


继续讨论代码示例2,我们需要在“condition2”和“function1(*p)”固定的条件下验证“condition1” 的“true”和“false”判定分支,之后继续固定“condition1”和“function1(*p)”验证“condition2” 的判定分支。


同样的,让我们在固定“condition1”和“condition2”的条件下讨论 “function1(*p)”。在其他分支条件固定的情况下验证某个分支条件的“true”和“false”值称作“MC/DC对”。MC/DC对一般 使用MC/DC真值表描述。表1就是一个MC/DC真值表示例。



在软件开发的不同阶段获取覆盖率

软件测试有很多种类,本文将其简要的分为三类:

> 系统/函数测试:测试集成后的整个应用

> 集成测试:测试集成的子系统

> 单元测试:测试一个或多个文件或类


每个软件项目在系统测试的过程中都会模拟最终用户的操作对源代码做一些系统测试。导致软件发布后仍旧存在缺陷最重要的一个原因通常是程序在运行过程中遇到了非预期的,即没有测试的输入组合。


很多软件项目并不是没有做集成测试或者单元测试。只是在完成集成测试或单元测试后,开发团队可能苦于为隔离程序中的单个或多个文必须所需的大量测试代码量。


对于最严格的单元测试和集成测试来说,最终生成的测试代码量比待测代码量还要庞大是很经常出现的情况。因此,这两种级别的测试普遍适用于关键和高安全领域,例如:航空航天、医疗、交通运输、工业过程控制、高速汽车等。此类软件中包含大量的嵌入式应用软件。


关键领域的结构化测试流程一般会将需求的级别高低作为重点,代码覆盖率因而会在这种“基于需求”的测试中进行分析。在许多项目中,高等级的需求最先被测试。此时代码覆盖率可以被用来检测和报告所达到的覆盖比例。


然而不幸的是,在系统测试和功能测试阶段想要达到100%的代码覆盖率几乎是不可能的。通常情况下系统测试和功能测试只能达到60%-70%的代码覆盖率,剩余30%-40%的代码覆盖率需要在单元测试和集成测试阶段才能够完成。


单元测试使用包含驱动和桩的测试代码隔离系统中的特定函数,同时使用测试用例模拟这些函数的执行。这些所谓的“低等级测试需求” 对被测试代码提供了更高的控制,可以提高先前执行的系统测试覆盖率(甚至能达到100%)。因此,在不同的测试之间共享覆盖率数据是非常有必要的。


嵌入式环境中获取覆盖率带来的挑战

常言道“有得必有失”,在嵌入式环境获取代码覆盖率的问题上,要付出的代价是对待测代码额外的插桩工作。插桩是将额外的代码添加到程序中,从而实现测试过程中的覆盖率收集和分析操作。


由于插桩的相关操作将导致程序源代码增多,进而延长程序的执行时间,因而需要预测插桩后的源代码的覆盖范围预测,尤其当测试实时嵌入式系统环境时,此项工作就更为重要。


事实上,要精准的预测程序文件插桩的影响几乎是不可能的。没有算法支持(也不可能有)。每个系统都包含很多的变量,具有独立唯一的复杂性。当然,对于典型的示例系统来说,获取一组准确的估计还是可能实现的。


在共享环境中获取覆盖率数据

在嵌入式环境下管理代码覆盖率的主要问题在于如何配置内存以容纳额外的插桩代码。VectorCAST针对大量示例代码评估后发现添加了上文中提出的各种覆盖率额外配置之后,源代码量增长量普遍达到了10%。对于绝大多数的32位目标板,这并不是一个很大的问题,但对于存储容量有限的8位或者16位目标板来说,几乎可以肯定这会是一个问题。


为了降低可执行文件的大小,各种各样的代码插桩技术被发明出来,针对不同大小的存储区域有不同的数据采集技术。植入存储器内部的收集系统可以用于监测被检测到的代码。这是插桩技术中保证使用最少RAM的关键技术。


4. 结语


通过以上的方法,可以统计C语言嵌入式代码覆盖率,统计结果为提高代码质量提供了有效的依据,也为衡量测试质量提供了重要的指标,并可以通过结果中的代码行执行次数进行效率分析。

然而,代码覆盖率并不能保证执行过的代码质量,也无法作为衡量生产力的指标,代码覆盖率的数据只能表明测试用例的覆盖代码的强度,只有保证测试用例的正确通过和较高的代码覆盖率相结合才能真正意义上提升代码的质量。


代码覆盖率能不能提高软件的可靠性?答案是肯定的,代码的覆盖率分析是保证软件质量最简便易行的方法。


END


版权归原作者所有,如有侵权,请联系删除。

推荐阅读

成功为华为“续命:中国芯片之父张汝京

一个工程师的“噩梦”:刚分清CPU和GPU,却发现还有……

这位“华为天才少年”,竟然要我用“充电宝”打《只狼》

嵌入式ARM 关注这个时代最火的嵌入式ARM,你想知道的都在这里。
评论 (0)
  • ‌亥姆霍兹线圈‌是由两组相同的线圈组成,线圈之间的距离等于它们的半径。当电流同时流过这两个线圈时,会在它们中间形成一个几乎均匀的磁场。这种设计克服了普通线圈磁场不均匀的缺陷,能够在中心区域形成稳定、均匀的磁场‌。‌亥姆霍兹线圈的应用领域‌包括材料、电子、生物、医疗、航空航天、化学、应用物理等各个学科。由于其操作简便且能够提供极微弱的磁场直至数百高斯的磁场,亥姆霍兹线圈在各研究所、高等院校及企业中被广泛用于物质磁性或检测实验。‌亥姆霍兹线圈可以根据不同的标准进行分类‌:‌按磁场方向分类‌:‌一维亥
    锦正茂科技 2025-04-09 17:20 93浏览
  •   物质扩散与污染物监测系统:环境守护的关键拼图   一、物质扩散原理剖析   物质扩散,本质上是物质在浓度梯度、温度梯度或者压力梯度等驱动力的作用下,从高浓度区域向低浓度区域迁移的过程。在环境科学范畴,物质扩散作为污染物在大气、水体以及土壤中迁移的关键机制,对污染物的分布态势、浓度动态变化以及环境风险程度有着直接且重大的影响。   应用案例   目前,已有多个物质扩散与污染物监测系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润物质扩散与污染物监测系统。这些成功案例为物质
    华盛恒辉l58ll334744 2025-04-09 11:24 95浏览
  •   卫星故障预警系统:守护卫星在轨安全的 “瞭望塔”   卫星故障预警系统作为保障卫星在轨安全运行的核心技术,集成多源数据监测、智能诊断算法与预警响应机制,实时监控卫星关键系统状态,精准预判故障。下面从系统架构、技术原理、应用场景以及发展趋势这四个关键维度展开深入解析。   应用案例   目前,已有多个卫星故障预警系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润卫星故障预警系统。这些成功案例为卫星故障预警系统的推广和应用提供了有力支持。   系统架构与组成   卫星故障
    华盛恒辉l58ll334744 2025-04-09 17:18 104浏览
  • 文/郭楚妤编辑/cc孙聪颖‍伴随贸易全球化的持续深入,跨境电商迎来蓬勃发展期,物流行业 “出海” 成为不可阻挡的必然趋势。加之国内快递市场渐趋饱和,存量竞争愈发激烈。在此背景下,国内头部快递企业为突破发展瓶颈,寻求新的增长曲线,纷纷将战略目光投向海外市场。2024 年,堪称中国物流企业出海进程中的关键节点,众多企业纷纷扬帆起航,开启海外拓展之旅。然而,在一片向好的行业发展表象下,部分跨境物流企业的经营状况却不容乐观。它们受困于激烈的市场竞争、不断攀升的运营成本,以及复杂的国际物流环境,陷入了微利
    华尔街科技眼 2025-04-09 15:15 144浏览
  •     前几天同事问我,电压到多少伏就不安全了?考虑到这位同事的非电专业背景,我做了最极端的答复——多少伏都不安全,非专业人员别摸带电的东西。    那么,是不是这么绝对呢?我查了一下标准,奇怪的知识增加了。    标准的名字值得玩味——《电流对人和家畜的效应》,GB/T 13870.5 (IEC 60749-5)。里面对人、牛、尸体分类讨论(搞硬件的牛马一时恍惚,不知道自己算哪种)。    触电是电流造成的生理效应
    电子知识打边炉 2025-04-09 22:35 138浏览
  • ‌液氮恒温器‌是一种利用液氮作为冷源的恒温装置,主要用于提供低温、恒温或变温环境,广泛应用于科研、工业和医疗等领域。液氮恒温器通过液氮的低温特性来实现降温效果,具有效率高、降温速度快、振动小、成本低等优点。 ‌液氮恒温器应用场景和领域:‌科研领域‌:‌低温物理实验‌:用于研究材料在低温下的各种物理特性,如超导性、磁性、电学性质等。‌半导体研究‌:在半导体制造和测试过程中,需要低温环境以测试半导体材料和器件的性能。‌超导研究‌:测量超导材料的超导转变温度、临界电流密度等参数。‌材料科学‌
    锦正茂科技 2025-04-09 16:32 55浏览
  • 贞光科技作为台湾Viking光颉电阻产品授权一级代理商,提供全系列高性能贴片电阻解决方案。本文详细介绍光颉AR/PR高精密薄膜电阻、CS/TCS电流感应电阻、LR合金电阻、CR/AR厚膜晶片电阻及PHV耐高压电阻的技术规格与应用场景,助力工程师精准选型。从高精度±0.01%到低温漂5ppm/℃,从微型0201到大功率应用,满足现代电子设计各类需求。全球电子产业快速发展,被动元件向小型化、高频化、高功率、耐压及抗湿方向演进。随着电子产品升级换代加速,应用领域多元化,与主流IC的兼容整合成为产品设计
    贞光科技 2025-04-09 16:50 86浏览
  • 政策驱动,AVAS成新能源车安全刚需随着全球碳中和目标的推进,新能源汽车产业迎来爆发式增长。据统计,2023年中国新能源汽车渗透率已突破35%,而欧盟法规明确要求2024年后新能效车型必须配备低速提示音系统(AVAS)。在此背景下,低速报警器作为车辆主动安全的核心组件,其技术性能直接关乎行人安全与法规合规性。基于WT2003H芯片开发的AVAS解决方案,以高可靠性、强定制化能力及智能场景适配特性,正成为行业技术升级的新标杆。WT2003H方案技术亮点解析全场景音效精准触发方案通过多传感器融合技术
    广州唯创电子 2025-04-10 08:53 141浏览
  • 引言:智能时代,语音交互的“进化力”在万物互联的智能硬件生态中,产品功能的迭代速度和用户体验的个性化需求日益提升。传统语音芯片“一次烧录,终身固化”的模式已无法满足市场快速变化的需求,OTA(Over-The-Air)远程升级技术正成为智能设备的核心竞争力。WT系列语音芯片,通过五大创新升级方案,为家电、医疗、教育、工业等领域的设备赋予“持续进化”的能力,让语音交互更智能、更灵活、更贴近用户需求。方案一:在板更新——极速调试,全球多语言敏捷响应代表芯片:WT588F02B-8S核心逻辑:在PCB
    广州唯创电子 2025-04-09 09:05 57浏览
  • 文/Leon编辑/侯煜‍就在小米SU7因高速交通事故、智驾性能受到质疑的时候,另一家中国领先的智驾解决方案供应商华为,低调地进行了一场重大人事变动。(详情见:雷军熬过黑夜,寄望小米SU7成为及时雨)4月4日上午,有网友发现余承东的职务发生了变化,华为官网、其个人微博认证信息为“常务董事,终端BG董事长”,不再包括“智能汽车解决方案BU董事长”。余承东的确不再兼任华为车BU董事长,但并非完全脱离华为的汽车业务,而是聚焦鸿蒙智行。据悉,华为方面寻求将车BU独立出去,但鸿蒙智行仍留在华为终端BG部门。
    华尔街科技眼 2025-04-09 15:28 144浏览
  • 引言:AI技术驱动智能交互新趋势在万物互联的智能时代,用户对产品的交互体验提出了更高要求——从“被动响应”向“主动对话”升级。如何将AI大模型的强大语义理解与语音交互能力轻量化集成至硬件产品中,成为厂商打造差异化竞争力的关键。WT2605C蓝牙语音芯片,凭借在线TTS、多引擎融合与极简开发特性,为智能硬件接入AI对话功能提供了“即插即用”的解决方案。核心优势:高度集成,让AI对话触手可及WT2605C芯片通过五大技术引擎的集成,重新定义语音交互芯片的边界:在线语音识别引擎:支持动态语音指令捕捉,
    广州唯创电子 2025-04-09 08:34 55浏览
  •   物质扩散与污染物监测系统软件:多领域环境守护的智能中枢   北京华盛恒辉物质扩散与污染物监测系统软件,作为一款融合了物质扩散模拟、污染物监测、数据分析以及可视化等多元功能的综合性工具,致力于为环境科学、公共安全、工业生产等诸多领域给予强有力的技术支撑。接下来,将从功能特性、应用场景、技术实现途径、未来发展趋势等多个维度对这类软件展开详尽介绍。   应用案例   目前,已有多个物质扩散与污染物监测系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润物质扩散与污染物监测系统。这
    华盛恒辉l58ll334744 2025-04-09 14:54 147浏览
  • ‌亥姆霍兹线圈‌是由两组相同的线圈组成,线圈之间的距离等于它们的半径。当电流同时流过这两个线圈时,会在它们中间形成一个几乎均匀的磁场。这种设计克服了普通线圈磁场不均匀的缺陷,能够在中心区域形成稳定、均匀的磁场‌。‌亥姆霍兹线圈的应用领域‌包括材料、电子、生物、医疗、航空航天、化学、应用物理等各个学科。由于其操作简便且能够提供极微弱的磁场直至数百高斯的磁场,亥姆霍兹线圈在各研究所、高等院校及企业中被广泛用于物质磁性或检测实验。‌‌亥姆霍兹线圈的用途非常广泛,主要包括以下几个方面‌:‌粒子物理实验‌
    锦正茂科技 2025-04-09 17:04 78浏览
  • 行业痛点:电动车智能化催生语音交互刚需随着全球短途出行市场爆发式增长,中国电动自行车保有量已突破3.5亿辆。新国标实施推动行业向智能化、安全化转型,传统蜂鸣器报警方式因音效单一、缺乏场景适配性等问题,难以满足用户对智能交互体验的需求。WT2003HX系列语音芯片,以高性能处理器架构与灵活开发平台,为两轮电动车提供从基础报警到智能交互的全栈语音解决方案。WT2003HX芯片技术优势深度解读1. 高品质硬件性能,重塑语音交互标准搭载32位RISC处理器,主频高达120MHz,确保复杂算法流畅运行支持
    广州唯创电子 2025-04-10 09:12 133浏览
  •   卫星故障预警系统软件:卫星在轨安全的智能护盾   北京华盛恒辉卫星故障预警系统软件,作为确保卫星在轨安全运行的关键利器,集成前沿的监测、诊断及预警技术,对卫星健康状况予以实时评估,提前预判潜在故障。下面将从核心功能、技术特性、应用场景以及发展走向等方面展开详尽阐述。   应用案例   目前,已有多个卫星故障预警系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润卫星故障预警系统。这些成功案例为卫星故障预警系统的推广和应用提供了有力支持。   核心功能   实时状态监测:
    华盛恒辉l58ll334744 2025-04-09 19:49 133浏览
我要评论
0
2
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦