【问题标题】:Free static checker for C99 codeC99 代码的免费静态检查器
【发布时间】:2011-02-12 16:46:57
【问题描述】:

我正在为 C99 代码(包括 GCC 扩展)寻找一个免费的静态检查器,它能够明确地说“这些预处理器宏总是被定义的”。

我需要最后一部分,因为我正在为单个目标处理器编译嵌入式代码。编译器(Microchip 的 C32,基于 GCC)根据所选处理器设置宏,然后在 PIC32 头文件中使用该宏来选择要包含的处理器特定头文件。因此,cppcheck 失败了,因为它检测到 30 个不同的 #ifdefs 用于选择众多可能的 PIC32 处理器之一,并尝试分析这些以及所有其他 #defines 的所有可能组合,但失败了。

例如,如果splint 可以处理 C99 代码,我会使用

splint -D__PIC32_FEATURE_SET__=460 -D__32MX460F512L__ \
-D__LANGUAGE_C__ -I/path/to/my/includes source.c

另外一个问题是 PIC32 工具链编译器被称为 pic32-gcc 而不仅仅是 gcc,尽管我还没有达到需要考虑这一点的地步。

更新 #1 - 我感兴趣但与这个问题正交的一件事是 Eclipse 集成(不必为 30 多个编译单元编写 makefile 就好了)。我在Eclipse forums 上询问了这个问题(尽管讨论更多关于集成到 Eclipse 中)。没有什么开创性的。

更新 #2 - 刚刚从 clang 尝试了 scan-build,使用:

scan-build --use-cc=/usr/local/bin/pic32-gcc make -B -k all

...(也没有--use-cc 标志)但我得到的只是典型的构建输出,其中一个示例是:

Building file: ../src/MoreMath.c
Invoking: PIC C32 C Compiler
pic32-gcc -D__DEBUG -I/usr/local/pic32-libs/include -O0 -Wall -c -fmessage-length=0 -std=gnu99 -Werror-implicit-function-declaration -MMD -MP -MF"src/MoreMath.d" -MT"src/MoreMath.d" -mprocessor=32MX460F512L -D__DEBUG -g -o"src/MoreMath.o" "../src/MoreMath.c"
Finished building: ../src/MoreMath.c

...最后:

Building target: MyBinary.elf
Invoking: PIC C32 C Linker
pic32-gcc -Wl,-Map,MyBinary.map -mprocessor=32MX460F512L --defsym=__MPLAB_DEBUG=1 -o"MyBinary.elf" <<ALL OF MY *.o FILES HERE>>
Finished building target: MyBinary.elf

scan-build: Removing directory '/tmp/scan-build-2010-06-21-1' because it contains no reports.

所以根据scan-build,我的代码要么是完美的,要么它什么也没做。我不确定什么是好的测试,看看它是否有效。

【问题讨论】:

  • 如果您的解决方案确实需要,您应该将要在 Eclipse 中使用的规定添加到您的问题中。
  • 不,这将是一个额外的好处。我将编辑问题以使其更清楚。我仍在努力让scan-build 使用 PIC32 工具链,如果我这样做了,我会接受下面的答案。
  • @Adam Davis - 我打算调整问题以更好地强调我对 PIC32 工具链的使用,但我不知道这是否会影响您提供赏金的动机。如果你想让我等一下,请告诉我。
  • 您好,我不是想问一个跑题的问题,但我很好奇。为什么有人要对微芯片进行编程?你在建什么?谢谢..
  • 微芯片是一些电子设备控制系统的一部分。它们几乎是完全自动的,因此它通过板载传感器(以及输入的数量很少)监控条件,并调整各种外围设备以维持某些操作状态。

标签: c gcc embedded static-analysis c99


【解决方案1】:

Clang's static analyzer 应该可以工作。

源代码#defines 的另一个选项是,您可以使用一些预处理器语句在源代码上运行cpp,然后通过静态分析器运行该结果代码。

【讨论】:

  • 我认为scan-build 已经达到了我所能得到的水平。我在 Eclipse 下开发并使用内部构建器(即没有明确的 makefile),我认为 Eclipse CDT 没有任何 clang 集成。切换到基于 makefile 的项目可能值得。
  • 唉,我看不到让 scan-build(或任何 Clang 工具)与 Eclipse 一起工作的方法。
  • @detly:为什么像你这样精通 C 的程序员会被 Eclipse 这样的邪恶所束缚?
  • @Matt Joiner - 你会推荐什么? (此外,我认为在这种情况下,它不是 Eclipse,只是扫描构建没有按我预期的方式工作。)
【解决方案2】:

您可以在标题的顶部添加一些这样的代码,以保证它已定义:

#ifndef MACRO_I_NEED
#error "MACRO_I_NEED should be defined"
#define MACRO_I_NEED  // to appease cppcheck
#endif

【讨论】:

  • 我不需要对每个源文件都这样做吗?
  • @detly:不一定——如果你有一个每个文件都包含的头文件(例如预编译的头文件),那么你可以把它放在最前面。
【解决方案3】:

不要使用带有clang的scan-build,而是考虑完全换掉gcc! Clang 的 C 支持是稳定的(并且尽最大努力模拟 gcc),并且应该可以很好地处理您的代码。

试试make -j3 CC=clang,看看会发生什么!

PS。这种语法可能完全错误。好久没用过makefile了(顺便说一句,CMake很棒)。

【讨论】:

  • 它不支持-MT选项,这意味着我必须重写很多makefile。当前构建使用自动依赖文件 - .d 文件 - 其中包含每个 .o 文件的头依赖项。我需要一段时间才能对此进行测试。
  • @detly,生成依赖文件并在你的 Makefile 中删除它们的处理(我想主要是模板)?
【解决方案4】:

根据您希望对代码运行的实际分析,您可以查看Frama-C。它使用您告诉它的任何 C 预处理器,因此您可以根据需要使用 PIC32 的 CPP。

【讨论】:

    【解决方案5】:

    这可能不会直接为您提供解决方案,但您可能会考虑查看 Coverity,它是一种专有的静态语法分析器,但对于 OS 项目是免费的。它应该可以满足您的需求!

    干杯!

    【讨论】:

      【解决方案6】:

      您可以使用sunifdef 之类的工具根据假定定义的宏对源代码进行部分预处理。您必须复制受这些定义影响的系统和库头文件并处理它们。然后在进行静态分析时,您将指定一个不同的包含路径,指向您已处理的标头。

      【讨论】:

      猜你喜欢
      • 2017-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-25
      • 1970-01-01
      • 2017-04-01
      • 1970-01-01
      相关资源
      最近更新 更多