Tag: 静态分析

跟踪未初始化的静态变量

我需要调试一个丑陋而庞大的数学C库,可能是由f2c生成的。 代码滥用本地静态变量,不幸的是它在某处似乎利用了这些自动初始化为0的事实。如果使用相同的输入两次调用其入口函数,则它会给出不同的结果。 如果我卸载库并重新加载它,它可以正常工作。 它需要很快,所以我想摆脱加载/卸载。 我的问题是如何使用valgrind或任何其他工具发现这些错误,而无需手动遍历整个代码。 我正在寻找声明本地静态变量的地方,先读取,然后再写。 由于静态变量有时会通过指针进一步传递(是的 – 它太丑了),这个问题更加复杂了。 我理解人们可以争辩说,自动工具不应该检测到这样的错误,因为在某些情况下,这正是预期的行为。 还有,有没有办法让自动初始化的本地静态变量“脏”?

如何在C中的初始化程序中使用static_assert?

信不信由你,我想在宏扩展到指定的初始化器中使用static_assert : #define INIT(N) \ /* static_assert((N) < 42, "too large"), */ \ [(N)] = (N) int array[99] = { INIT(1), INIT(2), INIT(42) }; 我想从INIT(42)发出错误,但取消注释static_assert是一个语法错误。 AFAIK static_assert在语法上是一个声明。 我如何在这个例子中使用它?

Frama-C anagram函数行为validation

我写了一个C函数,检查两个给定的字符串(C风格)是否是字谜。 我尝试用Frama-Cvalidation它,但它不能validation函数的最终行为(其他规范是有效的)。 第一个进入超时(即使WP中的超时值非常高),第二个未知。 这是代码: #include //@ ghost char alphabet[26] = {‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’, ‘p’, ‘q’, ‘r’, ‘s’, ‘t’, ‘u’, ‘v’, ‘w’, ‘x’, ‘y’, ‘z’}; /*@ // Takes a character and return it to lowercase if it’s uppercase axiomatic ToLower { logic char to_lower(char […]

具有(带符号)枚举值的按位运算

我正在使用标志的枚举器值: typedef enum { a = 0x00, b = 0x01u, // the u has no influence, as expected c = 0x02u, // the u has no influence, as expected … } enum_name; volatile unsigned char* reg = SomeAddress; *reg |= b; 根据MISRA-C:2004,不应使用带符号的类型进行按位操作。 不幸的是,我的编译器IAR使用signed int(或short或char)作为枚举的基础类型,我能找到的唯一选项与大小有关,而不是签名(“–enum-is-int”)。

确定“未知的评估顺序”

从版本1.80开始,Cppcheck告诉我 表达式’msg [ipos ++] =校验和(&msg [1],ipos-1)’取决于副作用的评估顺序 在此代码序列中(简化, data是变量) BYTE msg[MAX_MSG_SIZE]; // msg can be smaller, depending on data encoded int ipos = 0; msg[ipos++] = MSG_START; ipos += encode(&msg[ipos], data); msg[ipos++] = checksum(&msg[1], ipos-1); // <—- Undefined Behaviour? msg[ipos++] = MSG_END; // increment ipos to the actual size of msg 并将此视为错误,而不是可移植性问题。 它是C代码(包含在C ++主导的项目中),使用C ++ 98兼容编译器编译,同时按预期运行数十年。 […]

pdma中由circlema-c生成的圆节点的含义是什么

我使用frama-c工具来分析下面的代码。 int main (int argc, char *argv[]) { int i,a; for (i = 0; i < 100; i += 1) { a=0; if (a==0) { continue; } else { break; } } return 0; } cmd是 frama-c -pdg -dot-pdg graph main.c 我的问题是关于控制依赖性。 圈节点是什么意思? 我试着解释“while”节点,也许它代表一个时间循环,因为一个循环从“i <100”开始,所以有一个控制依赖(“i <100”—— o“while” )。 我猜对了吗? 但是什么是“休息”节点呢? 我猜那个节点“goto __Cont;” 与“休息”有关 “else”块中的语句。 我认为我没有明确的抽象模型来完全准确地理解控制依赖性。 […]

头文件中的函数原型与定义不匹配,如何捕获这个?

(我发现这个问题类似但不重复: 如何检查C编程语言中头文件的有效性 ) 我有一个函数实现,以及一个头文件中的不匹配原型(同名,不同类型)。 头文件包含在使用该函数的C文件中,但不包含在定义该函数的文件中。 这是一个最小的测试用例: header.h: void foo(int bar); FILE1.C: #include “header.h” int main (int argc, char * argv[]) { int x = 1; foo(x); return 0; } 文件2.c: #include typedef struct { int x; int y; } t_struct; void foo (t_struct *p_bar) { printf(“%x %x\n”, p_bar->x, p_bar->y); } 我可以使用VS 2010编译它,没有任何错误或警告,但毫不奇怪,当我运行它时会出现段错误。 编译器很好用(我明白了) 链接器没有捕获它(我有点惊讶) 静态分析工具(Coverity)没有抓住它(我非常惊讶)。 […]

使用gcc在C中键入typesafe varargs

很多时候我想要一个函数来接收可变数量的参数,例如以NULL结尾 #define push(stack_t stack, …) _push(__VARARG__, NULL); func _push(stack_t stack, char *s, …) { va_list args; va_start(args, s); while (s = va_arg(args, char*)) push_single(stack, s); } 如果foo收到非char*变量,我可以指示gcc或clang警告吗? 类似于__attribute__(format) ,但是对于同一指针类型的多个参数。

我可以使用哪些免费工具生成c代码的程序依赖图

我想从C源代码生成程序依赖图(PDG)。 我找到了解释它是怎么做的论文,但都使用了商业CodeSurfer工具。 有没有可以完成这项工作的免费工具或开源项目?

使用LLVM检测C / C ++代码

我想写一个LLVM传递来检测每个内存访问。 这是我想要做的。 给定任何C / C ++程序(如下面给出的那样),我试图在每次读取/写入/写入内存的指令之前和之后插入对某些函数的调用。 例如,考虑下面的C ++程序(Account.cpp) #include class Account { int balance; public: Account(int b) { balance = b; } ~Account(){ } int read() { int r; r = balance; return r; } void deposit(int n) { balance = balance + n; } void withdraw(int n) { int r = read(); balance = […]