如何避免静态分析的陷阱


17

我在一家在Joel Test(至少在纸上)上获得11分的公司工作。

但是实际上,没有什么能比预期的要好,该项目已经在DEFCON 1上进行了半年。现在,我的大多数同僚都高兴,如果他们可以在周日下午6:00回家。

使用静态分析工具是使我不工作的显而易见的好习惯之一。该项目都跟踪gcc -Wall警告和专有且非常昂贵的“ C / C ++”工具。

Gcc警告的确经常指向真实的(如果大部分时间都是无礼的)错误。

但是,专用工具列出了诸如隐式强制转换和字符串文字的sizeof之类的内容。隐式演员表也在其样式表中列入黑名单。

标准做法是迫使人们关闭每个警告。请注意,这确实排除了主要是误报的警告,这不是问题。

结果是:

  1. 人们向每个右值和每个参数添加类型转换,以隐藏过程中真正存在问题的类型不匹配。
  2. 人们引入一个错误,或者使用其他有问题的语言功能(用strlen代替sizeof,用strncpy代替strcpy,等等)。
  3. 警告被静默。
  4. 错误报告开始滚动。

主要要点是原始代码是由在语言能力范围内安全地工作的人编写的,而修正不是。

现在,我真的不认为可以挽救这家公司。但是,我想知道是否有一种更好的方法,最好是可以使用“专业”工具的方法,还是我应该避免完全使用它们,以防将来我自己做出决定。

不能假定所有程序员都是不能犯错的天才的解决方案。因为如果可以的话,那么首先就不需要使用这些工具。


1
旁注:除了«-Wall»以外,GCC还具有«-Wextra»选项,并且由于某些原因,两个metaoption中都未包含由于某些原因而未包括的更多警告。有关更多信息,请参阅文档。通常,如果每个选项都由metaoption启用,则都有提及。因此,要查找所有未启用的功能,您可能想要在整个文档中突出显示单词“ -Wall”和“ -Wextra»,然后您会看到尚未使用的单词。
Hi-Angel

我还要补充一点,我想知道GCC是否没有在“ -Wall”中包含很多“ -Wextra”。相信我,其中一些标志特别有用;至少这些警告使我摆脱了数小时的调试工作。
Hi-Angel

1
我很惊讶没有人在答案中提到代码审查。对我来说,试图偷偷摸摸地进行
骇客入侵的人

Answers:


16

但是实际上,没有什么能比预期的要好,该项目已经在DEFCON 1上进行了半年。现在,我的大多数同僚都高兴,如果他们可以在周日下午6:00回家。

这无疑是您的问题中很大一部分。软件工程师每周不能工作超过40个小时。如果超出此范围,则会严重损害您的工作能力-甚至每周工作80小时也不会给项目带来多少价值,有时项目甚至会退缩,因为团队引入的错误多于他们可以解决。如果您每周工作60个小时或更长时间已经半年了,那么您的整个团队都需要长时间休息,然后每周40个小时返回。劳力过度的工人很难解决任何无法解决的问题。

但是,专用工具列出了诸如隐式强制转换和字符串文字的sizeof之类的内容。隐式演员表也在其样式表中列入黑名单。

您确实需要完全删除该工具,或者重新配置/替换它。对每个隐式强制转换发出的警告对于任何人来说都是太多了。


您能否提供每周限制40小时的研究参考?

11
这里这里,仅供初学者使用。有大量文献证明,您每周不能进行超过40个小时的生产性工作。一个简单的Google会为您找到大量的文章。
DeadMG

5
进行两次小但重要的恕我直言的更正:每周40小时的限制是一个近似平均值,该规则仅适用于较长的时间段。团队可以在重要的截止日期之前投入额外的时间,然后再进行恢复(甚至可能需要休息几天),这是可以的。而且,时间限制因人而异,而且随着时间的推移而变化-有些人每周可以工作43个小时而不会出现问题,其他人只有35个工作日,而有些人在某些星期的工作效率要高于其他人。但是,连续加班超过两个星期确实会造成严重的麻烦。
彼得Török

13

我在一家在Joel Test(至少在纸上)上获得11分的公司工作。

该测试仅与软件公司相关。我不了解有关它的炒作。您可以得分12,但仍然有100%的垃圾程序员。人比工具重要得多。

但是,专用工具列出了诸如隐式强制转换和字符串文字的sizeof之类的内容。隐式演员表也在其样式表中列入黑名单。标准做法是迫使人们关闭每个警告。请注意,这确实排除了主要是误报的警告,这不是问题。

这是所有静态分析器面临的最大问题:过多的误报。解决此问题的唯一方法是详细了解为什么将工具设置为针对某个问题发出警告。只有这样,您才能对警告是否为假做出合理的假设。

对于隐式类型转换的特定转换,它的存在是由于C语言中一些非常常见,细微且危险的错误所致,这些错误是由C中的两个(moronic)隐式类型提升规则引起的。它们在形式上被称为整数提升规则通常的算术转换。我认为,只有不到十分之一的专业C程序员可以解释这两个规则的作用以及他们不做什么。但是,这些规则极其基础,在任何普通C程序的行之间都应用了数千次。

MISRA-C标准用了整整一章来解释这些危险的隐式转换规则,然后他们添加了许多相当复杂的规则来避免由隐式转换引起的错误。这对市场上的所有静态分析仪产生了相当大的影响。

我建议任何C程序员阅读MISRA-C章节,或至少阅读Google我提到的两个促销规则,并尽可能多地阅读它们。只有了解了这些规则的全部知识后,您才能忽略静态分析器。

现在,我真的不认为可以挽救这家公司。但是,我想知道是否有一种更好的方法,最好是可以使用“专业”工具的方法,还是我应该避免完全使用它们,以防将来我自己做出决定。

不能假定所有程序员都是不能犯错的天才的解决方案。因为如果可以的话,那么首先就不需要使用这些工具。

周围没有简单的方法。真正的问题实际上不是工具,而是晦涩的C语言。乍看之下,这似乎是一种轻松的语言,但是在行之间存在着许多不合逻辑和奇怪的机制。语言中还有数百种未定义/未指定/特定于行为的情况。他们中的大多数您必须学习并避免。

因此,您必须成为能够理解所有这些晦涩警告的资深C程序员,或者您必须与至少一个这样的人组成团队。只雇用一群初级程序员而又没有老手的公司不应该使用这些工具,也不能进行高完整性的软件开发。


我从一开始就花了点力气参加了测试,但这不是测试程序员的工具,而是测试雇主的工具。我想您可以将合适的同事包括为“金钱所能支付的最佳工具”。我想请您回答一下,以抛弃SA工具,并更好地雇用和/或培训。前一点似乎是共同点。

@qpr它也不会测试雇主,只是雇主愿意花钱进行软件开发。没有提到诸如招聘程序,企业目标,市场知识等内容。我认为大多数“ IT泡沫”公司在该测试中将获得12分,其管理层甚至不知道正在开发什么产品,或者根本不知道他们有什么市场。

4

目前尚不清楚您是要问如何解决该问题,还是首先应该如何避免它。我假设是后者。

听起来您一直在依靠静态分析作为检测和避免错误的主要方法。也许您最好将精力集中在单元测试和动态工具(例如内存检查器)上。

依靠会生成大量误报的工具是一个坏主意,尤其是在您无法抑制那些误报的情况下。它鼓励疲倦/过度劳累(或懒惰)的程序员进行“修正”以消除警告。如果您不能选择性地消除误报(例如带有注释)或定制规则集,那么您需要一个更好的工具。或者至少,您应该仅少量使用它。

听起来您的问题是人们粗心大意和/或由于劳累而犯错。也许您应该在代码审查上花费更多的时间/精力。这直接解决了您关于程序员不是天才的观点。

最后,听起来您可能在截止日期不切实际,资源匮乏和/或需求变化的情况下遭受了痛苦。这是一个管理问题,必须在该级别上解决……否则项​​目失败的风险会大大增加,并长期损害员工的生产力和士气。


3

除了user29079的出色答案之外,我还要补充一种C语言的不足,这增加了问题。在继续学习Java之前,我还没有意识到这种缺陷。

警告的目的是引起代码的作者和将来的读者注意以下事实:正在发生一些令人毛骨悚然的事件。作为一个概念,这完全可以:您启用的警告越多,发现的内容就越多。

完全错误的想法是,必须通过更改代码不惜一切代价修复每一个小麻烦。就是导致OP所描述的问题的原因:匆匆尝试通过更改代码而匆忙发出警告,而代码工作正常。

同时,我们不希望我们的代码每次编译时都会喷出数百条警告,因为警告很快就变得毫无意义,并且没有人再注意新的警告了。

因此,这似乎是目标冲突的情况。矛盾。

解决这个看似不可能的难题的一个很好的方法是能够在逐个语句的基础上有选择地抑制某种警告,以便我们可以在希望表明我们确实知道自己在做什么的地方精确地抑制它。必须更改任何代码。

Java使用@SuppressWarnings( "" )注解对此有一个很好的解决方案。举例来说,如果您使用Java 进行所谓的未经检查的转换,则编译器会发出警告以引起您的注意,然后进行检查,然后确定这是您知道自己在做什么的另外一种情况,所以你先于冒犯声明以@SuppressWarnings( "unchecked" )影响注释只有紧跟它的语句,你继续你的生活。

因此,警告消失了,代码保持不变,并且抑制注释停在那里,语法高亮显示为绿色,以证明发生了难于转换的事实,但作者承诺是好的。(*) 大家都开心。

在Java中,您甚至可以给单个参数加上函数前缀@SuppressWarnings(),以禁用只能在该特定参数上发出的特定警告。

但是,据我所知,C从来不支持任何标准机制来选择性地抑制语句警告,某些实现自己专有机制的编译器以精明的方式这样做,例如#pragma warning (nnn:N)Microsoft C 的指令。这些指令的问题是您需要两行指令,以便同时禁止单个语句的警告为随后的语句启用该警告。因此,即使C程序员知道该特定语句上的特定警告是可以的,也不太可能养成在单个语句基础上禁止显示警告的习惯。


(*)有人可能会争辩说,如果您允许这样做,那么屋子里的每个程序员都会压制警告而不会给予他们任何思考;答案是,您可以尽一切可能帮助程序员更好地完成工作,但是如果他们积极决定破坏您,则您将无能为力。


换句话说,尽管更改源代码以消除所有最后警告是良好实践的关键,但更改可编译代码却并非如此,因为它消除了无缘无故直接正确的简单代码。很好的区别。
内森·塔吉

2

我想说(不知道细节),您的公司犯了更严重的错误,而这只是症状:它无法正确确定所生产软件的领域,无法正确管理团队和定义合理的目标。

如果您的团队编写的软件对人类的生活至关重要,那么静态分析工具将非常重要且有用。由于错误的“成本”(以金钱衡量)(忽略了愤世嫉俗的程度)很高,因此需要专门的工具来完成这项工作。对于C和C ++,都有安全使用语言功能的准则(请阅读避免的内容以及避免使用的范围)。
但是,在这种情况下,让员工在周日工作是一个非常糟糕的主意,此外,根据您提供的背景,我推断,马虎的工作并不罕见。所以如果是这种情况,问题就非常非常大,您的管理层正在尝试使用“更好”的工具来解决它。不幸的是,事情并非如此。如果我要纠正的话,我会建议您开始寻找其他工作。关键任务软件如果做得不好,可能会困扰您并破坏您的专业声誉,更不用说诉讼前景了。

另一方面,如果您的团队所编写的内容不那么重要,那么具有较高假阳性率的“静态分析”工具只会使您放慢脚步,并且正如您所指出的,人们通常会对此做出反应找出其有效性的局部最大值,在这种情况下,只需在警告周围作弊即可,而不是试图解决根本原因。因此,根据您的情况,使用这些工具实际上可能会使源代码的质量下降,因此通常应避免使用它们。

如果需要管理正在编写一些C或C ++代码的软件团队,那么我首先要确定主要的项目目标是什么。如果编写无错误的代码至关重要(例如,适用于iOS和Android的超赞的新社交应用适合此操作),则可以使用静态分析,甚至可以进行正式规范和正式验证。但是,如果是这样的话,那么选择重要的程序员并让他们在合理的环境中工作,拥有足够的工作量和每周40小时的工作时间更为重要。

如果人们像奴隶一样对待人们,就不能负责任地工作(而占用我假期的人就是这样),而好的程序员只会定期拒绝这样做,除非他们不知道更好(如果他们很好,那么机会就很大)。他们是这样)。

底线:确定目标,然后确定使用的工具和流程,不要让可用的工具定义流程(达到目标),因为(坏)管理人员可能会强迫您。


1

如k.steff的回答所述,如果您在危急的情况下构建软件(飞机软件),则'C'静态分析工具非常有用,并且必须从第一天开始使用(而不是在开发几个月后出现不可复制的错误) )。

在开发过程的后期使用这些工具通常是在设计早期选择错误的标志。

在非关键软件中,这些工具可用于:-
压力管理,使它们感到有用(我们已经做了一些事情,我们花了很多钱来修复软件)。它使他们可以轻松地在PowerPoint报告中执行操作。
-让“有毒”的开发人员忙。让他们配置工具并分析工具结果,以便您有时间修复其讨厌的错误。
-强制执行编码规则。在这种情况下,必须从第一天开始使用。但是,好的代码检查工具可能是更好的选择。

因此,我的观点是,您必须避免使用此类昂贵且费时的工具,或使用它们使“有毒”人员忙碌。


1

我在一家在Joel Test(至少在纸上)上获得11分的公司工作。

通过Joel检验进行的验证不是对良好做法的衡量;不过,乔尔测试(Joel Test)导致的无效是对不良/遗漏行为的一种衡量。换句话说,可以认为这是必要的,但还不够。

现在,我的大多数同僚都高兴,如果他们可以在周日下午6点回家。

看来您有管理上的问题。系统性加班不是解决问题的解决方案。如果有的话,这是一种使事情看起来像正在运转并积累技术债务的解决方案。

现在,我真的不认为可以挽救这家公司。但是,我想知道是否有一种更好的方法,最好是可以使用“专业”工具的方法,还是我应该避免完全使用它们,以防将来我自己做出决定。

是的,有一种合理使用静态代码分析的方法。

它们可以而且通常确实提供很多价值。您只需要记住,(如编译器警告)静态分析工具最多(可以)提供一些错误提示-不是错误报告,也没有任何确定性。

听起来您的决策者将静态分析标志与应用程序缺陷混为一谈。

隐式演员表也在其样式表中列入黑名单。

这听起来像是管理能力问题,而不是静态分析问题。

结果是:

人们向每个右值和每个参数添加类型转换,以隐藏过程中真正存在问题的类型不匹配。

人们引入一个错误,或者使用其他有问题的语言功能(用strlen代替sizeof,用strncpy代替strcpy,等等)。

警告被静默。

错误报告开始滚动。

所有这些都是使定期报告看起来不错的方法,而不是解决代码中的问题的方法(看来您又遇到了管理能力问题)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.