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

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

3天内不再提示

使用静态分析查找并发错误

星星科技指导员 来源:嵌入式计算设计 作者:Paul Anderson 2022-07-09 07:10 次阅读

尽管几十年来小型化的进步已经为单处理器带来了巨大的性能提升,但这个时代似乎即将结束。使用单芯片实现显着额外性能的最佳选择是通过多个内核,但前提是软件可以编程以利用它们。

不幸的是,并发编程很困难。即使是只熟悉单线程编程的专家级程序员也常常无法理解并发程序容易受到诸如竞争条件、死锁和饥饿等全新类别的缺陷的影响。人类很难推理并发程序,并且编程语言本身的某些方面不适合并发。因此,专家们经常偶然发现这些危害。以下讨论描述了常见的并发缺陷,并解释了静态分析工具如何在不执行程序的情况下发现此类缺陷。

竞争条件的后果

当多个执行线程访问一个共享的数据并且其中至少一个线程在没有显式同步操作来分离访问的情况下更改该数据的值时,就会出现竞争条件。根据两个线程的交错,系统可能会处于不一致的状态。

种族条件特别阴险,因为它们可以无限期地潜伏而未被发现,并且只在极少数情况下出现,表现出难以诊断和重现的神秘症状。特别是,它们很可能通过对已部署软件的测试而存活下来。充其量,这意味着增加开发时间;在最坏的情况下,后果可能是毁灭性的。

2003 年东北大停电如此普遍的一个原因是计算机化能源管理系统中的竞争条件导致向运营商传达误导性信息。正如 Kevin Poulsen 在 2004 年的一篇文章 ( www.securityfocus.com/news/8412 ) 中指出的那样,“该漏洞有一个以毫秒为单位的机会窗口。” 在测试过程中出现此类问题的可能性微乎其微。在另一种情况下,iOS 4.0 到 4.1(现已修复)中的竞争条件意味着任何可以物理访问 iPhone 3G 或更高版本的人都可以在某些条件下绕过其密码锁定。

图 1 显示了一个简单竞争条件的示例。带有入口和出口传感器的制造装配线维护当前生产线上的项目的运行计数。每次项目进入行时,此计数都会增加,每次项目到达行尾并退出时,此计数就会减少。如果一个项目在另一个项目退出的同时进入该行,则计数应该递增然后递减(或反之亦然),以使净变化为零。但是,正常的递增和递减不是原子操作;它们由一系列单独的指令组成,这些指令首先从内存中加载值,然后在本地对其进行修改,最后将其存储回内存中。如果更新事务是在没有足够保护措施的多线程系统中处理的,由于传感器读取和写入共享数据:计数,因此可能会出现竞争条件。图 1 中的交错导致错误计数为 69。也有可能导致错误计数为 71 的交错,以及一些正确导致计数为 70 的交错。

图 1:竞争条件导致装配线上的项目计数不正确。

poYBAGLCrp6Ab6iLAAFNNb5eg0I645.png

对于这个例子和一般的竞争条件错误,标准调试技术可能由于几个原因而无效。

很少发生意味着发现问题的机会减少。如果问题不经常出现,它可能永远不会在测试期间出现。这个问题是双重的。首先,两个线程中可能的指令交错数量可能很大,并且随着指令数量的增加而急剧增加。这种现象被称为组合爆炸。如果线程 A 执行M条指令,线程 B 执行N条指令,则两个线程的可能交错为:

等式 1

poYBAGLCrqeANHacAAAxJkAc4zk487.png

例如,给定两个普通线程,每个线程有 10 条指令,则指令有 184,756 种可能的交错。现实世界的软件庞大而复杂;测试每一个交织是根本不可能的。其次,即使测试人员可以识别出一些值得检查的交错,也很难设置测试用例来确保它们确实发生,因为线程调度可能是高度不确定的。

如果详尽的测试难以解决,那么开发人员可以做什么?一种非常有用的方法是静态分析。CodeSonar 等高级静态分析工具使用高度复杂的符号执行技术同时考虑许多可能的执行路径和交错。这些技术可以在不需要执行程序的情况下找到竞争条件和其他并发错误。

有几个因素使比赛状况诊断变得困难。首先,症状可能令人困惑。在图 1 示例中,运行计数通常是正确的,但有时太高,有时太低。其次,不习惯考虑多线程编程的特定缺陷的程序员可能会在可能出现竞争条件之前花费大量时间对代码感到困惑。高级静态分析工具在这方面特别有用。他们通过检查共享内存位置的访问模式来识别竞争条件;也就是说,他们关注的是种族本身,而不是它的症状。当识别出竞争条件时,高级静态分析工具将报告它以及支持信息,以帮助用户进行评估和调试。程序员的负担大大减轻。

更复杂,更多错误

竞争条件通常通过使用锁来保护共享资源来避免。但是,锁可能会引入性能瓶颈,可能会阻止程序充分利用多核的潜力,因此程序员在使用它们时必须小心谨慎。编写有效使用锁的代码可能很棘手,这种复杂性可能导致一组不同的问题,即死锁和饥饿。

在死锁中,两个或多个线程相互阻止,因为每个线程都持有另一个线程需要的锁。图 2 显示了如何使用用于保护两个共享变量的两个锁出现死锁。在此示例中,多条装配线共享当前正在装配的项目总数,第二个 bad_items 值记录有多少成品未通过质量控制。一个线程在 count 上获得锁,另一个在 bad_items 上获得锁。两个线程都无法获得它需要的第二个锁;因此既不能执行它的操作,也不能到达释放锁的地步。由于两个更新都无法完成,因此两个线程都完全卡住了。

图 2:在两个线程之间的死锁中,两个线程都无法前进。

pYYBAGLCrq2Aad9iAAI2eenIfqA226.png

静态分析工具可以通过标记不同线程可以以不同顺序获取相同锁的情况来识别存在死锁风险的软件,例如图 2 中所示的线程。消除所有这些情况足以确保系统不会陷入死锁。

饥饿是使用锁的多线程程序中发生的另一个问题。如果一个线程正在等待另一个线程当前持有的资源需要很长时间,它可能会饿死。例如,假设上述制造自动化系统包括一个定期审核线程,该线程检查所有进入和退出记录,以确保运行计数与进入的项目总数相匹配,而退出的项目总数更少。审计线程需要锁定计数和所有传感器,因此所有更新都必须等待审计完成。如果审核运行很长时间,更新可能会显着延迟。如果运行时间过长,下一次审计可能会设法获取所有锁并在未完成的线程取得任何进展之前开始运行。在最坏的情况下,部分或全部更新可能永远没有机会运行。

静态分析可以通过提出诸如“在持有锁时是否调用长时间运行的库函数?”之类的问题来提供重要的价值。CodeSonar 等工具还为用户提供了添加自己检查的机制。如果已知内部函数 f() 具有较长的运行时间,工程师可以添加自定义检查,每当持有一个或多个锁的线程调用 f() 时触发警告。

多线程为嵌入式开发人员必须考虑的潜在错误添加了全新的类别,使得查找各种错误变得更加困难。最新一代的静态分析工具可以帮助解决这两个问题。

审核编辑:郭婷

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

    关注

    2550

    文章

    51035

    浏览量

    753083
  • 嵌入式
    +关注

    关注

    5082

    文章

    19104

    浏览量

    304825
  • 计算机
    +关注

    关注

    19

    文章

    7488

    浏览量

    87854
收藏 人收藏

    评论

    相关推荐

    Linux文件查找

    Linux文件查找 1.find查找概述 为什么要有文件查找,因为很多时候我们可能会忘了某个文件所在的位置,此时就需要通过find来查找。 find命令可以根据不同的条件来进行
    的头像 发表于 12-03 17:09 238次阅读

    如何使用Ozone分析Cortex-M异常

    Ozone可以帮助用户快速分析查找导致CPU故障的软件bug。本文解释如何使用Ozone的调试功能,深入了解Cortex-M架构上的这些错误
    的头像 发表于 11-29 11:14 675次阅读
    如何使用Ozone<b class='flag-5'>分析</b>Cortex-M异常

    汽车异构硬件平台开发如何进行静态代码分析

    先进的静态代码分析工具,其新版本中引入的多CCT功能为开发人员提供了强大的支持,该功能不仅简化了多编译器环境下的代码分析过程,还可以极大增强代码的质量和安全性。
    的头像 发表于 10-09 16:15 508次阅读
    汽车异构硬件平台开发如何进行<b class='flag-5'>静态</b>代码<b class='flag-5'>分析</b>

    Perforce静态分析工具2024.2新增功能:Helix QAC全新CI/CD集成支持、Klocwork分析引擎改进和安全增强

    ​和Klocwork的最新版本对静态分析工具进行了重大改进,通过尽早修复错误、降低开发成本和加快发布速度,使开发团队实现左移。本文中,我们将概述2024.2版本的新特性和新功能。CI/CD和左移以
    的头像 发表于 10-08 16:22 274次阅读
    Perforce<b class='flag-5'>静态</b><b class='flag-5'>分析</b>工具2024.2新增功能:Helix QAC全新CI/CD集成支持、Klocwork<b class='flag-5'>分析</b>引擎改进和安全增强

    如何查找线路漏电的方法和步骤

    线路漏电是电气设备和线路中常见的故障之一,它不仅会导致设备损坏,还可能引发火灾等安全事故。因此,查找和处理线路漏电问题至关重要。 确定漏电类型 首先,我们需要确定漏电的类型。漏电分为两种:一种是接地
    的头像 发表于 08-26 09:07 1642次阅读

    中性点接地10 kV线路故障的查找方法

    随着社会对供电可靠性的要求越来越高,快速查找10 kV线路故障显得越来越重要。鉴于此,从各种技术、管理手段出发,分析查找中性点接地10 kV线路故障的方法,以求达到提高供电可靠性的目的。
    的头像 发表于 08-13 17:08 131次阅读
    中性点接地10 kV线路故障的<b class='flag-5'>查找</b>方法

    并发物联网云平台是什么

    并发物联网云平台是一种能够处理大量设备同时连接并进行数据交换的云计算平台。这种平台通常被设计用来应对来自数以万计甚至数十亿计的物联网设备的并发请求,保证系统的稳定性和响应速度。 首先,从技术层面
    的头像 发表于 08-13 13:50 249次阅读

    基于ANSYS的高速磨削电主轴动静态性能分析

    以国产120MD60Y6型高速磨削电主轴为研究对象,使用有限元分析方法,基于ANSYS Workbench建立高速电主轴模型,先分析静态特性,计算工作条件下电主轴前端所受径向力和轴承径向刚度;然后
    的头像 发表于 08-05 11:20 152次阅读
    基于ANSYS的高速磨削电主轴动<b class='flag-5'>静态</b>性能<b class='flag-5'>分析</b>

    IAR通过多架构认证的静态分析工具加速代码质量自动化

    公司推出经TÜV SÜD认证的C-STAT静态分析工具,适用于最新发布的IAR Embedded Workbench for RISC-V V3.30.2功能安全版。
    的头像 发表于 06-19 15:49 375次阅读

    有线以太网TCP转无线wifi 双频2.4G+5.8G网关配置步骤

    无线静态STA桥接:由上级AP(路由器/服务器)分配固定的IP/MAC地址供模块链接,这样实现了AP(路由器/服务器)控制多个终端,从而达到每个终端收发指令及采集数据和上级网络具备唯一对应指向性,防止信号干扰和数据丢包、转发错误等问题,实时在线监控每一台独立终端运行状态达
    的头像 发表于 06-13 10:58 852次阅读
    有线以太网TCP转无线wifi 双频2.4G+5.8G网关配置步骤

    如何用C语言实现高效查找(二分法)

    今天给分享一下使用C语言实现二分算法,主要包含以下几部分内容:二分查找算法介绍二分查找算法使用场景二分查找算法代码实现二分查找算法实现过程用C语言实现二分法
    的头像 发表于 06-04 08:04 1105次阅读
    如何用C语言实现高效<b class='flag-5'>查找</b>(二分法)

    如何设置静态IP代理

    静态IP
    jf_60146132
    发布于 :2024年04月29日 07:46:31

    浅谈船舶电气接地故障的查找及解决方法

    。作为影响供电可靠性因素之一的电气绝缘性能逐渐成为各方关注的。文章对电力系统接地故障进行分析,并提出查找及解决方法,以期为相关工程案例提供参考。 关键词:船舶电气;接地故障;查找及解决方法 0引言 随着现代船舶电气自动化程度的
    的头像 发表于 03-14 10:20 698次阅读
    浅谈船舶电气接地故障的<b class='flag-5'>查找</b>及解决方法

    HarmonyOS如何使用异步并发能力进行开发

    一、并发概述 并发是指在同一时间段内,能够处理多个任务的能力。为了提升应用的响应速度与帧率,以及防止耗时任务对主线程的干扰,HarmonyOS系统提供了异步并发和多线程并发两种处理策略
    的头像 发表于 02-18 09:18 526次阅读

    ug内部错误,内存访问违例怎么解决

    问题,并提供一些预防这些问题的最佳实践方法。 一、内部错误原因和解决方法 1. 软件错误:软件错误是引起内部错误的最常见原因之一。这可能是由于编程
    的头像 发表于 12-27 16:27 6267次阅读