0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

将静态分析与编译器和数据库集成

星星科技指导员 来源:嵌入式计算设计 作者:S. Tucker Taft 2022-06-28 14:09 次阅读

静态分析工具正越来越多地集成到软件开发过程中。在过程中保存来自编译器的数据、更改历史记录和错误信息,而不是作为后置代码步骤,可以提高静态分析的效率。

高级静态分析工具在嵌入式系统开发中变得越来越重要。远远超出实际上是编码风格检查器的旧静态分析工具,新工具静态分析源程序的控制和数据流,从而检测错误和漏洞,例如潜在的缓冲区溢出、未初始化变量的使用、通过空指针访问,以及对安全攻击(SQL 注入、跨站点脚本等)的敏感性。

然而,这些先进的工具提出了几个问题。首先,工具需要了解被分析程序的语义——也就是说,它们必须编译程序——以执行所需的控制和数据流分析。为此,它们必须紧密集成到构建环境中,以便在编译时识别和使用所有可能需要的包含文件或其他规范模块。其次,这些高级工具产生的输出量可能令人望而生畏,每条诊断信息都需要仔细审查,以确定它是否反映了一个真正的问题,如果是,如何解决它。

将静态分析工具与软件开发工具链更紧密地集成可以缓解这两个挑战。在第一种情况下,将静态分析工具与编译器紧密集成在很大程度上消除了构建环境问题,并使用户界面变得简单和熟悉。在第二种情况下,可以通过将所有输出存储在历史数据库中来管理大量输出,从而允许程序员专注于已知良好版本和源当前状态之间的增量,而不是在每一步处理所有消息。

与编译器集成

超越简单语法检查的静态分析工具通常需要编译器前端的大部分功能,以便它可以根据程序的语义进行分析。这是因为相同的句法形式通常可以根据其成分的含义有不同的解释。例如,Ada 中的表达式 F(N) 可能(除其他外)是数组引用、函数调用或类型转换。

访问程序的底层语义允许该工具跟随程序中出现的每个名称回到引入该名称的声明,即使存在重载、通用模板或重命名也是如此。该工具将知道每个对象和每个表达式的类型,并将识别任何隐式运行时检查发生的位置。这些隐式运行时检查可能包括对取消引用空指针的检查和对数组边界之外的索引的检查。即使没有隐式运行时检查的语言也可以将某些运行时操作定义为具有未指定的语义,例如整数算术溢出或超出范围的数组索引。静态分析工具需要知道语言语义何时允许这种未指定(因此不可预测)的行为。

由于需要包含编译器前端的强大功能,许多静态分析工具都建立在感兴趣的语言的现有编译器技术之上。不幸的是,该工具的构建者选择的编译器技术可能与该工具的客户使用的编译器无关。发生这种情况时,静态分析工具可能无法处理客户编写的代码。

例如,如果客户程序使用编译器特定的功能(例如中断处理或特殊的内存映射工具),则无法保证静态分析工具的底层完全或以同样的方式支持它们。编译器前端技术。即使对于可移植代码,客户的编译器和静态分析工具的底层技术也可能存在不同的错误或对语言规则的细微不同的解释。即使解释匹配,编译程序的命令(控制源代码搜索路径、预处理器支持和其他功能的命令行开关)也可能有很大不同。因此,复杂程序的构建过程可能难以转换为对程序执行静态分析的生成过程。

为了解决这些问题,明确的解决方案是将高级静态分析引擎与客户使用的相同编译器技术集成。因此,静态分析引擎必须在某种程度上独立于任何特定编译器技术使用的中间表示,以便该工具可以轻松地适应支持多个编译器前端。

一种方法是让静态分析引擎拥有自己的中间表示,专门设计用于支持工具执行的高级分析。适应支持新的编译器前端需要编写一个转换模块,将编译器的中间表示(前端的输出)转换为静态分析引擎使用的程序表示。翻译模块将结果输出到文件中供以后使用。中间语言翻译器既可以链接到编译器前端,也可以作为独立程序运行,读取编译器的中间表示,转换它,然后写出分析引擎的中间表示。这个过程如图 1 所示。

图 1:中间语言翻译器读取编译器的中间表示,对其进行转换,然后写出静态分析引擎的中间表示。

poYBAGK6my-AVZT4AAMKOJXCdmI208.png

当采用这种集成方法时,静态分析只是构建过程的另一部分,可以在编译期间执行,或者为了利用整个程序分析,在链接步骤期间执行。对用户的一个关键优势是调用静态分析工具只涉及向编译器和/或链接器提供额外的命令行开关。无需为该工具创建专门的构建脚本或维护两组源(一组与编译器一起使用,另一组与静态分析工具一起使用)。

与开发环境集成

由于软件开发通常通过 Eclipse 等图形集成开发环境 (IDE) 进行,因此将静态分析工具和编译器集成到 IDE 中是很自然的。然后,程序员将立即熟悉该工具的整体界面,从而减少学习曲线并增加定期使用该工具的可能性。

静态分析工具生成的消息必须像编译器生成的错误或警告消息一样处理,并由用户以相同的方式管理和查看。鉴于正在使用多个 IDE,每个 IDE 都有自己的消息格式,静态分析工具将需要表示其消息,以便可以轻松地将它们转换为 IDE 期望的任何格式。

消息表示的自然选择是 XML,因为它使用标记的、自描述的方法来捕获消息特征。使用 XML 的一个附带好处是它有助于简化应用程序的国际化过程,从而可以以客户喜欢的自然语言显示消息。

与历史数据库集成

一旦高级静态分析工具与编译器和 IDE 集成,下一个问题就是处理此类工具可能提供的大量消息。因为高级静态分析工具正在寻找可能的运行时逻辑错误和安全漏洞,所以它们必须模拟运行时程序的执行(识别一组潜在的执行状态)并确定在什么条件下可能会达到不期望的状态。不幸的是,这很少是简单的“是”或“否”。有许多灰色阴影,其中脆弱性程度取决于工具可能未知或超出其分析能力的因素。

这个问题有时用健全性与精确性来表述。如果一个搜索有问题结构的工具能够识别出它正在寻找的所有问题(没有误报),那么它就被认为是可靠的。但稳健性通常是以牺牲精度为代价的。该工具可能会生成大量误报,这些误报是用于识别并非真正问题的警告或错误。考虑这个使用类 C 语法的简单示例:

int k, m, n;

... // Complicated code that assigns a positive value to m

... // and that does not assign to n

if (m《0){

k=n;

...

}

工具可能无法推断 if 语句上的 m《0 条件为假,因此可能会警告 if 语句的主体引用未初始化的变量 (n)。实际问题恰恰相反:if 语句的主体是永远不会执行的代码,有时称为死代码或无法访问的代码。

工具开发人员必须决定是选择健全性(确保没有未被检测到的实际违规)还是精度(确保所有报告的违规都是真正的错误)。当一个工具用于安全关键或高安全性系统时,天平就会倾斜。使用此类工具的开发人员必须有信心检测到所有违规行为。但这引发了前面提到的关于如何处理可能产生的大量误报的问题。当该工具应用于遗留软件(在应用静态分析工具之前开发的代码)时,这个问题尤其明显。对于大型应用程序,用户需要查看的消息数量可能令人望而生畏。

将高级静态分析工具与历史数据库集成,可以有效地使用该工具,最大限度地减少误报导致的问题,即使对于在使用该工具之前开发的复杂应用程序也是如此。关键概念是基线的概念以及该工具突出显示相对于此类基线的增量的能力。通过在历史数据库中记录每个工具运行的所有结果,该工具可以识别任何两次运行之间的增量(更改)。

数据变得更有用

为了使分析运行之间的比较有效地进行,消息必须是唯一可识别的,而不涉及特定的行号,可以从源代码的一个版本切换到另一个版本而无需任何重大更改。识别没有行号的消息的一种方法是记录消息的文本(或相应的 XML),以及它出现的函数的名称,如果消息的文本与同一功能中的一些先前消息。

假设消息使用这个与行号无关的唯一标识符作为关键字存储在数据库中,那么该工具可以轻松识别给定消息是新消息还是先前生成的消息。这使历史数据库的整体大小保持可管理。该工具不需要为工具的所有调用重复存储所有消息的文本,而只需要存储给定消息的文本一次,以及该消息出现的工具调用范围的指示(第一次运行生成消息的位置,以及第一次没有出现的运行)。

该历史数据库使用户界面可以直接显示或突出显示自指定基线以来的新消息。这使得该工具即使在具有大量遗留代码的大型应用程序上也能有效使用。应用程序的已知良好版本可以通过分析工具作为基线运行。可以分析应用程序的当前开发版本,并将分析此已知良好版本的结果作为基线。那些在开发版本上工作的人可以专注于与他们自已知良好版本以来所做的更改相关的任何消息,而不必费力地处理与遗留代码相关的消息。最终,可以致力于处理这些积压的消息,

与历史数据库集成的另一个好处是能够从查看分析结果的用户那里收集评论。在某些情况下,可能需要对特定消息进行大量调查以了解可能的影响。捕获这项工作很重要。历史数据库是记录用户学习内容的自然场所。

另外,如果用户确定所识别的代码是安全可靠的,历史数据库可以记录该给定消息应该从后续输出中被抑制,并且可以记录抑制该消息的支持理由。或者,如果需要更改识别的代码,历史数据库可以记录分配给问题的程序故障报告 (PTR) ID,从而允许问题跟踪系统和分析工具的历史结果之间的可追溯性。当该工具检测到具有关联 PTR ID 的消息消失时,可以将其配置为直接通知问题跟踪系统可以关闭关联的 PTR 记录。自动化关闭 PTR 的过程可以显着减轻通常负担过重的质量保证团队的负担。

静态分析作为开发过程的关键组成部分

随着应用程序变得越来越大和越来越复杂,高级静态分析工具在现代软件开发中发挥着关键作用,它显着减少了查找可能危及系统可靠性、安全性或安全性的错误和漏洞所需的工作量。但许多组织尚未充分利用这些工具,通常是因为将它们纳入日常软件开发过程(构建、回归测试和其他步骤)可能存在很高的进入障碍。

如前所述,两个重要的步骤可以减少这种进入障碍:工具与编译器技术和历史数据库的集成。这不仅仅是一个理论上的提议。CodePeer 是由 SofCheck 和 AdaCore 联合开发的高级静态分析工具,作为 Ada 的自动代码审查器。该工具已完全集成到 AdaCore 的 GNAT Pro Ada 开发环境中,并可通过 GNAT Programming Studio IDE 调用。

与编译器的集成在很大程度上消除了将源代码移植到分析工具的挑战。成功编译源代码的同一编译器前端还可以生成高级静态分析引擎进行更深入分析所需的中间表示。此外,相同的命令行开关、源代码结构和 make 文件可用于编译和静态分析代码。编译器前端将自动处理应用程序使用的任何特定于实现的功能。

降低进入壁垒的第二个主要步骤是与历史数据库的集成,这使得在大型系统上工作的开发人员可以专注于他们最近的更改,并将审查以前发布的遗留代码中的问题推迟到更合适的时间。此外,与数据库的集成允许开发人员记录审查工具输出的结果以及决定隐藏消息或将其归档为 PTR 的理由。最后,数据库会自动验证修复并关闭 PTR。通过这两个步骤,静态分析可以成为嵌入式软件开发人员工具箱中重要且高效的工具。

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5082

    文章

    19104

    浏览量

    304785
  • 编译器
    +关注

    关注

    1

    文章

    1623

    浏览量

    49107
收藏 人收藏

    评论

    相关推荐

    分享关于编译器的科普

    源代码分析工具和IDE集成。GCC被构建成一个单一的静态编译器,这使得它非常难以被作为API并集成到其他工具中。 GCC比Clang支
    的头像 发表于 12-09 09:49 82次阅读

    云原生和数据库哪个好一些?

    云原生和数据库哪个好一些?云原生和数据库各有其独特的优势,适用于不同的场景。云原生强调高效资源利用、快速开发部署和高可伸缩性,适合需要高度灵活性和快速迭代的应用。而数据库则注重数据一致
    的头像 发表于 11-29 10:07 127次阅读

    多维表格数据库Teable的适用场景?

    Teable多维表格数据库是一款功能强大的云端数据库和协作工具,结合了电子表格的灵活性和数据库的强大功能,适用企业内部项目管理 数据收集与整理 内容管理与创意协作 客户关系管理 项目跟
    的头像 发表于 10-31 15:48 182次阅读

    数据库数据恢复—通过拼接数据库碎片恢复SQLserver数据库

    一个运行在存储上的SQLServer数据库,有1000多个文件,大小几十TB。数据库每10天生成一个NDF文件,每个NDF几百GB大小。数据库包含两个LDF文件。 存储损坏,数据库
    的头像 发表于 10-31 13:21 197次阅读
    <b class='flag-5'>数据库</b><b class='flag-5'>数据</b>恢复—通过拼接<b class='flag-5'>数据库</b>碎片恢复SQLserver<b class='flag-5'>数据库</b>

    应用和数据库部署在不同的物理服务上有什么优点?

    应用服务和数据库服务分开部署在不同的物理服务上,或者至少在不同的虚拟机上,通常是一个推荐的做法。这样做有以下几个优点:   1、安全性:分离可以提高系统的安全性。如果应用服务
    的头像 发表于 10-08 11:28 213次阅读

    数据库数据恢复—SQL Server数据库出现823错误的数据恢复案例

    SQL Server数据库故障: SQL Server附加数据库出现错误823,附加数据库失败。数据库没有备份,无法通过备份恢复数据库
    的头像 发表于 09-20 11:46 338次阅读
    <b class='flag-5'>数据库</b><b class='flag-5'>数据</b>恢复—SQL Server<b class='flag-5'>数据库</b>出现823错误的<b class='flag-5'>数据</b>恢复案例

    AI编译器技术剖析

    随着人工智能技术的飞速发展,AI编译器作为一种新兴的编译技术逐渐进入人们的视野。AI编译器不仅具备传统编译器的功能,如高级语言编写的源代码
    的头像 发表于 07-17 18:28 1615次阅读

    人工智能编译器与传统编译器的区别

    人工智能编译器(AI编译器)与传统编译器在多个方面存在显著的差异。这些差异主要体现在设计目标、功能特性、优化策略、适用范围以及技术复杂性等方面。以下是对两者区别的详细探讨,旨在全面解析其内在差异。
    的头像 发表于 07-17 18:19 1834次阅读

    恒讯科技分析:sql数据库怎么用?

    。 2、安装数据库软件: 在您的服务或本地计算机上安装所选的数据库软件。 3、配置数据库服务: 根据需要配置
    的头像 发表于 07-15 14:40 343次阅读

    数据库数据恢复—SQL Server数据库所在分区空间不足报错的数据恢复案例

    SQL Server数据库数据恢复环境: 某品牌服务存储中有两组raid5磁盘阵列。操作系统层面跑着SQL Server数据库,SQL Server
    的头像 发表于 07-10 13:54 477次阅读

    数据库数据恢复—raid5阵列上层Sql Server数据库数据恢复案例

    数据库数据恢复环境: 5块硬盘组建一组RAID5阵列,划分LUN供windows系统服务器使用。windows系统服务内运行了Sql Server数据库,存储空间在操作系统层面划分
    的头像 发表于 05-08 11:43 503次阅读
    <b class='flag-5'>数据库</b><b class='flag-5'>数据</b>恢复—raid5阵列上层Sql Server<b class='flag-5'>数据库</b><b class='flag-5'>数据</b>恢复案例

    MongoDB数据恢复—MongoDB数据库文件损坏的数据恢复案例

    服务数据恢复环境: 一台Windows Server操作系统服务,服务上部署MongoDB数据库。 MongoDB
    的头像 发表于 04-23 14:48 400次阅读
    MongoDB<b class='flag-5'>数据</b>恢复—MongoDB<b class='flag-5'>数据库</b>文件损坏的<b class='flag-5'>数据</b>恢复案例

    数据库数据恢复—Sql Server数据库文件丢失的数据恢复案例

    不能确定数据存储位置。 数据库文件丢失后服务仍处于开机状态,所幸没有大量数据写入。 raid5中所有磁盘编号后取出,经过硬件工程师检
    的头像 发表于 04-11 15:38 876次阅读
    <b class='flag-5'>数据库</b><b class='flag-5'>数据</b>恢复—Sql Server<b class='flag-5'>数据库</b>文件丢失的<b class='flag-5'>数据</b>恢复案例

    如何编译静态集成到PSoC™ Creator中?

    你好 我正在使用博世 BME680 EVAL_PASCO2_SENSOR 。 我还必须将 Bosch BSEC 集成到我的项目中,该对EVAL_PASCO2_SENSOR数据执行后
    发表于 03-06 08:07

    数据库数据恢复】Oracle数据库ASM实例无法挂载的数据恢复案例

    oracle数据库ASM磁盘组掉线,ASM实例不能挂载。数据库管理员尝试修复数据库,但是没有成功。
    的头像 发表于 02-01 17:39 514次阅读
    【<b class='flag-5'>数据库</b><b class='flag-5'>数据</b>恢复】Oracle<b class='flag-5'>数据库</b>ASM实例无法挂载的<b class='flag-5'>数据</b>恢复案例