开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情
代码检测
静态检测 cppcheck
-
工具:
cppcheck -
安装:
sudo apt install cppcheck -
使用: 具体使用可以参考
cppcheck -h,以及官方手册。# 目录 unitest/src ├── CMakeLists.txt ├── ref.cpp ├── sizeof_.cc # 正常 └── string_.cpp # 有内存泄漏-
检测指定的文件:
cppcheck string_.cppunitest/src$ cppcheck string_.cpp Checking string_.cpp ... [string_.cpp:12]: (error) Memory leak: pt # 12行:错误类型为error,错误信息是:Memory leak,变量pt unitest/src$ cppcheck sizeof_.cc Checking sizeof_.cc ... -
检测指定的目录:
cppcheck srcunitest$ cppcheck src Checking src/ref.cpp ... 1/3 files checked 33% done Checking src/sizeof_.cc ... 2/3 files checked 66% done Checking src/string_.cpp ... [src/string_.cpp:12]: (error) Memory leak: pt # 检测出来 3/3 files checked 100% done -
不检测指定某个文件或者目录:加上参数
-i。如果屏蔽多个文件,每个前面都要加-i。# 不检测src/下的`sizeof_.cc`文件 unitest$ cppcheck -i src/sizeof_.cc src Checking src/ref.cpp ... 1/2 files checked 50% done Checking src/string_.cpp ... [src/string_.cpp:12]: (error) Memory leak: pt 2/2 files checked 100% done -
严重性质等级
cppcheck --enable=<id> file,具体使用可以参考:cppcheck -h。error:在发现bug时候使用warning:阻止bug的建议style:stylistic issues related to code cleanupperformance:对于代码性能的建议。portability:可移植性问题。代码在32/64位不同的平台上可能不能工作。information:配置问题。仅在配置时候使用
-
将检测结果输入到文件中 使用
shell的管道重定向:cppcheck string_.cpp --quiet 2> checkInfo.txt # --quiet 是为了不在控制台打印 # 2>checkInfo.txt 实现将错误信息重定向到checkInfo.txt -
配合
CMake- 在
CMake的build目录下使用:cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .这样会自动在该目录下生成compile_commands.json - 然后在运行:
cppcheck --project=compile_commands.json。 也可以将错误信息重定向到输出文件:cppcheck --project=compile_commands.json 2>checkInfo.txt。
- 在
-
动态检测 valgrind
-
安装:
sudo apt install valgrind -
--tool=<name>:name=Memcheck:默认工具。 主要是针对内存进行检测,比如:未初始化的内存、使用已经释放的内存、内存访问越界等。name=Callgrind:检查程序中函数调用过程中的问题。name=Cachegrind:检查程序中缓存使用出现的问题。name=Helgrind:用来检查多线程程序中出现的竞争问题。name=Massif:检查程序中堆栈使用中的问题。Extension:利用core提供的功能,自己编写特定的内存调试工具。
为了使valgrind发现的错误更精确,如能够定位到源代码行,建议在编译时加上 -g 参数,编译优化选项请选择O0,虽然这会降低程序的执行效率,也可以使用CMake产生可执行文件。
-
未
new的内存进行delete// valgrind_1.cc #include<iostream> void fun() { int* ptr = new int[10]; ptr[0] = 10; return ; } int main(int argc, char const *argv[]) { fun(); return 0; } 运行
valgrind --log-file=checkInfo.txt --leak-check=full ./valgrind_1--log-file=checkInfo.txt: 将输出信息重定向到文件中--leak-check=full:显示详细的错误 其他参数参考valgrind -h
最好配合cppcheck一起使用,有些问题可能valgrind因为编译器的问题检测不出。比如:使用未初始化的内存
int main(int argc, char const *argv[]) {
int a[4];
int i, s;
a[0] = a[1] = 0;
for(int i=0; i<4; i++)
s += a[i];
return 0;
}
可能由于编译器的版本不同,valgrind工具没有检测出使用未初始化的内存问题,但是cppcheck检出。
src$ cppcheck valgrind_2.cc
Checking valgrind_2.cc ...
[valgrind_2.cc:8]: (error) Uninitialized variable: s