本文翻译自官方文档 pclp-sca
1、概述
Vector Informatik GmbH 开发的静态分析工具受到全球几乎所有行业成千上万家企业的信赖。我们的用户群中有很大一部分利用我们的工具来开发嵌入式和安全关键型环境的应用程序。长期以来,我们通过实施嵌入式编译器使用的语言扩展、支持各种 MISRA 编码标准以及增加诊断功能来解决嵌入式开发人员的具体问题,为这一群体提供支持。 作为我们对嵌入式和安全关键型开发人员社区持续承诺的一部分,我们为在此类环境中使用 PC-lint Plus 编写了本指南。
本指南提供
最佳实践清单,遵循该清单将有助于最大限度地正确使用 PC-lint Plus,使您意识到潜在问题的领域、避免或检测异常操作的步骤,以及支持稳健套料环境的策略建议。
讨论环境因素以及 PC-lint Plus 在运行时可能受到的环境影响。
2、在安全关键应用中使用 PC-lint Plus 的最佳实践
2.1 确保配置正确
开发一个包含库头文件的简短测试程序,并使用所依赖的编译器特定功能。在该程序上运行 PC-lint Plus,以确保其产生正确的结果,并确保在处理库头文件时不会产生错误。
在使用新的库头文件之前,创建一个包含这些头文件的空 C 或 C++ 文件,并在该文件上运行 PC-lint Plus。在使用这些库头文件的任何生产代码上运行 PC-lint Plus 之前,确保库头文件产生的任何错误都已得到解决。
2.2 针对特定目的验证工具
我们建议使用测试线束来确保 PC-lint 满足您的需求和期望,从而建立对 PC-lint Plus 配置的信心,并针对特定目的验证其功能。
例如,如果您依赖 PC-lint Plus 来检测特定的 MISRA 违规行为,则应 1) 查看我们的文档以确定所声称的支持级别;2) 查看并理解与规则支持声明相关的任何文档注意事项;3) 创建包含已知 MISRA 规则违规行为的测试,并验证 PC-lint Plus 是否使用您的配置生成预期的相应诊断。
应定期运行此类测试,包括在使用 PC-lint Plus 的新设施、更改配置和升级 PC-lint Plus 时。保持此类测试有助于 "增强使用信心",提供正常运行的证据,并快速识别潜在问题。
2.3 了解选项的处理方式及其影响范围
PC-lint Plus 按选项出现的顺序进行处理,并允许在命令行、lint 配置文件、LINT 环境变量以及源代码中的 lint 注释中提供选项。虽然这提供了极大的灵活性,但了解选项的范围、在不同阶段使用选项的影响以及选项之间的相互作用(包括选项如何撤销之前的选项)也很重要。
由于选项是按顺序处理的,因此要确保在处理主配置之前,先处理受这些选项影响的源代码。这通常需要一个或多个包含所需选项的文件,以及一个包含要处理的源文件名称的单独文件。然后在列表文件之前的命令行中指定配置文件。
需要记住的是,在源代码处理前指定的许多选项,都可以通过源代码模块中的 lint 注释来覆盖(源代码模块中的选项范围仅限于出现这些选项的模块)。
2.4 了解选项对诊断信息传递的直接影响
所有选项都会以某种方式影响 PC-lint Plus 的行为,因此可能会影响分析结果。因此,在使用选项前应了解其功能。有些选项的主要目的是直接影响诊断信息的发布。抑制选项
是最明显的例子,因为它们的存在完全是为了控制诊断结果的发送。还有其他一些选项可以直接影响诊断程序的行为,包括
控制哪些文件或文件区域被视为库的选项,包括 -libh、+libh、-libm、+libm、-libdir、+libdir、-library和+libclass以及flb标志选项。由于库代码通常比非库代码受到的审查更少,这些选项可能会直接影响对受这些选项影响的文件发出的诊断。
-limit和++limit选项可以人为地将发出的诊断数量限制在一个提供的值。
-misra_interpret和+misra_interpret选项可更改某些信息的发布标准。
-skip_function(跳过函数)选项会使 PC-lint Plus 跳过指定函数的主体,从而有效地阻止对该函数的分析。
单元检查(-unit_check)选项会禁用全局打包以及在全局打包阶段发出的信息。
全局打包阶段发出的信息。
flf标志选项控制对库函数定义进行分析的程度。
fia标志选项控制是否发出补充信息。
某些标志选项(如fcv和fdx)通过改变发布信息的标准,直接影响信息的发布。
2.5 防止关键信息被抑制
可能需要防止压制某些报文。 例如,项目政策可能不允许偏离某些特定的规则,在这种情况下,相应的信息就不应该被压制。
++efreeze选项可用于防止抑制整个警告级别或信息模式。例如,++efreeze(w1)可以阻止抑制所有错误、
++efreeze(123)可以防止压制信息 123,而 ++efreeze(123?) 则可以防止压制信息 123。 则会阻止报文 1230-1239。++efreeze选项在其出现的选项上下文中是不可逆转的(尽管可以使用-env_pop和-env_restore选项切换到另一个选项上下文,详见《参考手册》),在该选项之后出现的抑制信息对被冻结的信息没有任何影响。 请注意,诸如在++efreeze选项之前出现的-esym选项不受影响,在++efreeze选项之后,它仍可能对信息抑制决策产生影响。
除了永久的 ++efreeze 选项外,还有一个 +efreeze版本,除了可以用相应的 -efreeze 选项中止其作用外,其他都是一样的。
2.6 不要压制信息 686 - 选项可疑
信息 686 是对可能产生意外行为或意外副作用的选项发出警告的工具,这些选项不应被抑制或忽略。解决 686 消息的方法应包括了解产生该消息的原因,然后对导致该消息的选项进行适当调整。 在配置开头的选项 ++efreeze(686) 可用来确保消息不会被抑制。
2.7 启用库文件的 686 消息
库文件的默认警告级别为 1,这使得 PC-lint Plus 只对库文件发出错误信息。由于是警告而不是错误,因此默认情况下不会为库文件报告消息 686。库文件通常不包含 lint 选项,但如果包含这些选项,它们的作用就会显现出来,因此应报告在库文件中执行的可疑选项。可以使用选项 +elib(686) 启用库文件的 686 消息。
2.8 请勿使用-wlib(0)或-w0选项
-wlib(0)选项会抑制来自库代码的所有消息,而 -w0选项会抑制来自所有代码的所有消息。这些选项不应用于对安全至关重要的应用程序,因为它们甚至会阻止最严重的错误发生。而-wlib(1)和-w1选项则安全得多。
使用 -wlib(0) 和 -w0选项通常有以下四个原因:
(1)消除来自库头文件的错误。
使用-wlib(0)选项试图压制源于库头文件的信息绝不是明智之举。这种做法只能掩盖问题的表象,而不能从根本上解决问题。因此,以后遇到的源代码可能无法得到正确的评估,从而导致不可靠的输出。
库头文件产生的错误通常是配置不完整或不正确造成的。应努力了解问题的原因,并在此基础上解决问题。
如果库文件不在您的优化策略范围内,可能需要抑制库文件中的非错误信息。在这种情况下,应使用-elib*选项来限制对库文件的抑制效果。
(2)创建一块 "净土",以便启用特定信息。
不包含基本错误信息的 "白板 "不是好做法。即使后来启用了错误信息,也可能会有一段时间没有发出严重的信息,从而掩盖了基本问题。
(3)当 PC-lint Plus 被用于标准分析以外的目的时:
在这种情况下,-w0 选项与-stack_info 等选项一起使用,标准输出将不会被使用。虽然在这种模式下运行 lint 时,标准输出可能不是重点,但抑制错误信息仍可能隐藏一些严重问题,导致不正确或不完整的操作。-w1选项是一个更好的选择。
(4)当 PC-lint 用于测试或故障排除时。
测试或故障排除不太可能证明使用这些选项是合理的,但如果此类测试不会对项目造成不利影响,则可以允许使用这些选项,因为此类操作不在项目范围之内。
使用-wlib(0)或-w0 会导致 686 消息警告,如警告 686:选项"-wlib(0)"是可疑的,因为"有可能导致无意义的输出";在库文件中收到语法错误很可能意味着你的 Lint 配置出了问题。
如前所述,消息 686 绝不应被抑制。
2.9 不要使用信息模式完全由问号和/或星号组成的抑制选项
如果压制选项的信息模式是一个或多个星号,那么它将有效压制该选项范围内的所有信息。例如,-elib(*) 与-wlib(0) 具有相同的效果,因此需要同样谨慎。
具有相同的效果,因此也有相同的注意事项。同样,-e* 与 -w0 的效果相同。对于像 -efunc 这样的作用域抑制选项,也应避免使用 *的信息模式。
例如,-efunc(*,foo)将禁用 foo 函数正文中的所有信息。这可能是一个错误,也可能是试图抑制处理 foo 时出现的几条不同的信息。在后一种情况下,更稳妥的做法是抑制单个信息,以免日后对 foo 的修改在无意中造成严重问题。
完全由问号组成的抑制模式与星号的处理方式相同。例如,-e??等同于-e*,将抑制所有选项,而不仅仅是编号为 10-99 的选项。由于这种行为,任何仅由问号组成的信息抑制模式都值得怀疑,因为这意味着对该选项的行为方式存在误解。
2.10 考虑使用+flm 选项锁定报文格式
PC-lint 生成的报文格式由 -h、-width 和各种 -format选项控制。
-格式选项来控制。可以使用 -os 选项将输出重定向到指定文件。如果 PC-lint 的输出被自动化系统处理,那么信息的格式就非常重要,因为格式不当的信息可能会导致系统无法解析信息而丢失信息。
为防止在处理过程中意外更改报文格式(如源代码中的 lint 注释中提供的恶意 -format 选项),建议在配置格式后立即使用 +flm 选项。+flm标志选项将导致未来的-h、-width、-format和-os选项将被忽略,直到遇到-flm 选项。
2.11 不要使用+fce选项
+fce选项指示 PC-lint Plus 在遇到 #error 指令时继续处理。虽然该选项对故障排除很有用,但不应在生产环境中使用。遇到#error指令通常表示配置错误,如宏定义丢失或不正确。在出现此类指令后强制继续处理会掩盖此类问题,并可能导致分析不完整或不正确。
2.12 请勿使用+fcs选项
+fcs选项指示 PC-lint Plus 在遇到静态断言失败时继续处理。与上文所述的 +fce 一样,虽然该选项对故障排除很有用,但不应在生产环境中使用。静态断言失败通常表明存在配置错误,如宏定义缺失或不正确。在这种情况下强行继续处理会掩盖此类问题,并可能导致分析不完整或不正确。
2.13 如果必须检查库代码,请使用 +flf 选项
库函数定义通常不会被处理,这意味着不会对这些函数进行相应的分析。这样做有几个原因:
通常不希望收到有关库函数实现的信息,因为这些信息通常不在分析范围内。
这些定义可能包含特定于实现的构造,而 PC-lint 在不进行额外配置的情况下是不支持这些构造的。
不处理此类定义可节省少量时间。
如果库代码应接受与项目代码相同的分析,可使用+flf 选项强制进行适当的分析。
2.14 确认项目头从未被标记为库头文件
使用 verbosity 选项-vf在包含头文件时产生 verbosity 输出。这将输出
包含 example.h 文件(库)
表示库头文件,或
包含文件 example.h (hdr)
否则。确保绝不将项目头文件包含为(库),因为这将把其符号标记为库符号,并抑制为库代码禁用的信息。
2.15 使用 -function和-sem选项强制执行函数语义
PC-lint Plus 包含许多标准 C 函数语义的固有知识。 例如,调用 exit 或 abort 永远不会返回,fgets 可能返回一个空指针,或者 memchr 的第三个参数不应大于第一个参数给出的缓冲区大小,这些都是 lint 知道的。
使用 -function 选项,可以将这些相同的语义复制到用户定义的函数中。使用 -sem 选项可以定义全新的语义。为用户定义的函数指定语义不仅可以记录函数的假设和要求,还能为 lint 提供有关函数使用的更多信息,从而进行更全面的分析。
有关更多信息,请参阅《参考手册》中的 "语义 "一章。
2.16 查看新版本的修订历史,了解软件中可能存在的缺陷
PC-lint Plus 的每个版本都会在《参考手册》的 "修订历史 "一章中记录有关产品更改的详细信息。对这些更改的描述简要概述了新功能、现有行为的更改以及已纠正的错误。在升级之前,了解对软件所做的更改以及这些更改可能对项目产生的影响非常重要,但同样重要的是要查看已修复的错误,以了解如果不升级 lint 软件还会存在哪些缺陷。建议在使用新版本之前,对每个版本的所有修订历史项目进行审查,并评估所述更改的潜在影响。
2.17 始终使用+e900 以确保成功完成处理
+e900选项将启用信息 900。信息 900 会在工序结束时发出,以表明工序已成功完成,并说明已生成的信息数量和已处理的模块数量。生成的报文数不包括 900 报文本身。
如果 PC-lint Plus 遇到致命错误或以其他方式提前终止,则不会生成消息 900,因此消息 900 的存在表明分析已全部完成。此外,900 信息中指定的已生成信息数量可与外部系统收到的信息数量进行比较,其中任何差异都表示可能存在信息格式或解析问题。信息 900 所报告的模块数量同样可以与 PC-lint Plus 预计分析的模块数量进行比较。
2.18 管理 PC-lint Plus 中的缺陷
与所有复杂的软件产品一样,PC-lint Plus 也存在缺陷。我们的《参考手册》中公布了已知的问题和限制,但用户可能会遇到新的问题。 当发现潜在缺陷时,应向 Vector Informatik GmbH 报告,以便对问题进行验证和纠正。重要的是要了解缺陷的影响范围,并将缺陷和所提供的解决方法记录在案。
2.19 记录环境变量的使用
虽然 PC-lint 的大部分配置都是通过纯文本配置文件实现的,但有两个可选的环境变量可以改变 PC-lint 的行为。参考手册》中记录了这两个变量:LINT和 INCLUDE。如果在启动 PC-lint 时设置了 LINT 环境变量,其内容将被预置到参数列表中。 如果设置了 INCLUDE 环境变量,则会按照《参考手册》第 15.2.1 节的规定,使用指定的目录列表搜索文件。
PC-lint 还提供了一个选项 -incvar,允许为 INCLUDE 环境变量指定一个替代名称。在这种情况下,PC-lint 将使用所提供的环境变量的值,而不是 INCLUDE。
最后要注意的是,用户创建的间接文件(配置文件)可能包含对任意环境变量的引用,以指定文件的位置和某些支持扩展环境变量的选项(如 -i 选项)。这种扩展比较容易发现,因为它们必须用符号包围,如 PATH。 在项目的 lint 配置中使用任何环境变量都应记录在案。
2.20 与 PC-lint Plus 可执行文件的平台差异
PC-lint Plus 以本地二进制文件的形式发布,适用于 Windows、macOS 和 Linux。这些版本之间的功能差异如下
在 Windows 版本中,ffff标志的默认值为 ON,而在其他版本中则为 OFF。
+dump_queries 选项的初始默认子选项相当于
在Linux 和 macOS 版本中相当于 +dump_queries(unicode,colors,nocompact),在 Windows版本中相当于 +dump_queries(nounicode,nocolors,nocompact)。
3、环境因素
3.1 动态链接库
Windows 版 PC-lint Plus 所需的动态链接库 (dll) 包括
SHELL32.dll
ole32.dll
KERNEL32.dll
ADVAPI32.dll
包含许可证管理软件的 PC-lint Plus 版本可能额外需要以下 dll,其功能仅用于许可证验证目的:
IPHLPAPI.DLL
WS2_32.dll
USER32.dll
OLEAUT32.dll
3.2 Windows 注册表
PC-lint Plus 不以任何方式使用 Windows 注册表。
3.3 安装目录
PC-lint Plus 的安装包括 PC-lint Plus 可执行文件和一组零或多个配置文件。如果可执行文件被删除,程序将无法运行(不存在)。如果删除了一个或多个配置文件,其效果将基于剩余配置和被删除文件的内容。如果 PC-lint Plus 无法找到或打开引用的配置文件,则会出现致命错误信息并终止程序(这是默认行为)。
3.4 并行执行
在执行过程中,可以指示 PC-lint Plus 将输出写入文件。 例如,-oe和-os选项可指定标准错误和标准输出的写入位置,-write_file 选项可用于将数据写入任意文件,-pch 选项可导致写入预编译头文件,-summary 和 -stack 选项可指示将输出写入文件。当一个实例可能写入的文件与另一个实例可能读取或写入的文件有可能重叠时,建议不要同时运行 PC-lint Plus 实例。
PC-lint Plus 不使用系统范围内的共享资源(如共享内存),通常也不会创建临时文件,因此在不同项目上运行多个 PC-lint Plus 实例应该是安全的,但上述注意事项除外。 请注意,- max_threads选项可用于在一个项目上安全地执行多线程分析,方法是使用多个分析线程,这些线程使用互斥来防止上述竞赛条件。
3.5 有限的处理资源
在 CPU 资源有限的情况下,PC-lint 的处理时间可能会比正常情况下长,但不会有其他影响。PC-lint 的分析结果也不会受到影响。
3.6 内存资源有限
PC-lint 会在处理过程中的不同阶段分配 RAM,使用的 RAM 数量会因多种因素(包括正在处理的文件大小和内容以及正在执行的通过次数)的不同而有很大差异。 如果操作系统无法满足 PC-lint 对内存的请求,程序将提前终止,并且不会产生上文所述的信息 900。