Clang Static Analyzer (5) Clangsa 原创 精华
Clang Static Analyzer (5) Clangsa
接着本系列之前的文章,补充下CodeChecker的部分用法。使用命令CodeChecker analyzers
可以查看当前支持的静态分析检查器analyzers。如果安装了Cppcheck就会展示出来,clangsa和Clang-tidy是LLVM Clang编译工具链提供的静态分析检查器。
在使用CodeChecker
静态分析时,可以使用选项[--analyzers ANALYZER [ANALYZER ...]
指定只使能部分分析器,这些ANALYZER可以是clangsa
、cppcheck
、clang-tidy
。如下:
系列文章中的前几篇中,已经到了Cppcheck和Clang-tidy这2个静态检查分析器,本文快速介绍下clangsa静态检查分析器。
1、clangsa介绍
前面系列文章介绍了Clang Static Analyzer,知道Clang 静态分析器CSA是一个源代码分析工具,可查找 C、C++ 和 Objective-C 程序的bugs。Clang Static Analyzer可以理解提供了两部分内容,一部分是CSA工具,比如scan-build、CodeChecker,还有一部分是clangsa,虽然是Clang Static Analyzer的缩写,但是指的是Clang Static Analyzer的静态检查分析器,定义了一些的代码缺陷检查规则。详细可以参考链接https://clang.llvm.org/docs/ClangStaticAnalyzer.html,除了支持的检查器,还有用户文档和开发文档,用于支持定制自己的检查器。
本文主要学习下clangsa支持的检查器Available Checkers
。
clangsa
、cppcheck
、clang-tidy
属于分析器analyzer,每个分析器定义了自己的一套检查器“checkers”。检查器还会通过分组进行管理。clangsa
分析器的检查器分为三组,分别为:
- Default Checkers 默认检查器,可以发现安全和API使用缺陷,死代码和其他逻辑错误。。请参阅下面的默认检查器列表。
- Experimental Checkers 实验检查器也称为alpha checkers,处于开发过程中,默认关闭。可能会崩溃,也可能产生较多的误报。
- Debug Checkers 调测检查器被分析器开发者用作调测目的
2、Default Checkers 默认检查器
默认检查器分为如下几组。只关注C、C++相关的检查器,osx、Fuchsia、nullability、WebKit可以自行按需了解。
- core 核心语言特性,通用的检查器
- cplusplus C++语言检查器
- deadcode 死代码检查器
- nullability Objective-C空指针传递和解引用检查器
- optin 可移植、性能或编程风格相关的检查器
- security 安全相关检查器
- unix POSIX/Unix检查器
- osx macOS检查器
- Fuchsia Fuchsia操作系统相关的检查器。Fuchsia是Google开发的一款开源操作系统。
- WebKit WebKit相关检查器。WebKit是开源Web浏览器引擎。
2.1 core检查器
core检查器关注语言的核心特性,包含通用目的的检查器,例如除零错误,空指针解引用,使用未初始化的值等。这些检查器需要一直开启,其他检查器依赖这些核心检查器。
- core.CallAndMessage (C, C++, ObjC)
检查函数调用的逻辑错误,Objective-C消息表达错误,例如,未初始化参数,空函数指针等。适用于C, C++, ObjC等编程语言。
-
core.DivideZero (C, C++, ObjC)
检查是否存在除零错误。 -
core.NullDereference (C, C++, ObjC)
检查空指针的解引用错误。SuppressAddressSpaces
选项会屏蔽带地址空间的空指针解引用告警。可以使用选项-analyzer-config core.NullDereference:SuppressAddressSpaces=false
来关注该SuppressAddressSpaces
。默认是开启的。
- core.StackAddressEscape ©
检查堆栈越界,在一个函数内部声明的局部变量存储在栈空间上,不能把该变量的地址传递到函数外部。
- core.UndefinedBinaryOperatorResult ©
检查二元表达式中的未定义的值。
- core.VLASize ©
检查变长数组(Variable Length Arrays,VLA)的长度未定义或者零值。
- core.uninitialized.ArraySubscript ©
检查未初始化的值用作数组下标。
- core.uninitialized.Assign ©
检查使用未初始化的值进行赋值。
- core.uninitialized.Branch ©
检查未初始化的值用于条件分支。
- core.uninitialized.CapturedBlockVariable ©
检查代码块捕获未初始化的值。
- core.uninitialized.UndefReturn ©
检查未初始化的值传递到外层函数。
2.2 cplusplus检查器
C++语言相关的检查器。
-
cplusplus.InnerPointer (C++)
检查在re/deallocation之后使用的C容器的内部指针。C标准库中的许多容器方法会让指向容器元素的引用无效,包含实际引用,迭代器,原生指针(raw pointers)。使用无效的引用会引起未定义行为,这通常是C++中内存错误的源头,也是该检查致力于检查出来的代码缺陷。
该检查器只是适合std::string对象,不能识别出复杂的用法,比如传递std::string_view这样的unowned指针。
-
cplusplus.NewDelete (C++)
检查重复释放double-free和释放后使用UAF等内存问题。追踪被new/delete管理的内存。
- cplusplus.NewDeleteLeaks (C++)
检查内存泄露memory leaks. 追踪new/delete管理的内存。
- cplusplus.PlacementNewChecker (C++)
Check if default placement new is provided with pointers to sufficient storage capacity. 检查缺省的定位new(placement new)指针操作,有足够的存储能力。
-
cplusplus.SelfAssignment (C++)
检查C++的自赋值的copy 和 move赋值操作。 -
cplusplus.StringChecker (C++)
检查 std::string 操作。检查从std::string对象构造的cstring是否为空NULL。如果检查器不能推断出该指针为空,会假设其非空,用于满足构造。
该检查器可以检查SEI CERT C++编程规则STR51-CPP。不要从空指针创建std::string对象。
2.3 deadcode检查器
-
deadcode.DeadStores ©
检查存储在变量里的值后续未被使用。WarnForDeadNestedAssignments
选项会使能检查器来检测嵌套的无用的赋值代码,可以使用选项-analyzer-config deadcode.DeadStores:WarnForDeadNestedAssignments=false
来关闭该选项。WarnForDeadNestedAssignments`选项默认开启。
会对这样的代码进行告警,例如: if ((y = make_int())) { }
。
2.4 security检查器
- security.FloatLoopCounter ©
浮点数作为循环变量 (CERT: FLP30-C, FLP30-CPP).
- security.insecureAPI.UncheckedReturn ©
Warn on uses of functions whose return values must be always checked.
-
security.insecureAPI.bcmp ©
Warn on uses of the ‘bcmp’ function. -
security.insecureAPI.bcopy ©
Warn on uses of the ‘bcopy’ function. -
security.insecureAPI.bzero ( C )
Warn on uses of the ‘bzero’ function. -
security.insecureAPI.getpw ©
Warn on uses of the ‘getpw’ function. -
security.insecureAPI.gets ©
Warn on uses of the ‘gets’ function. -
security.insecureAPI.mkstemp ©
Warn when ‘mkstemp’ is passed fewer than 6 X’s in the format string. -
security.insecureAPI.mktemp ©
Warn on uses of the mktemp function. -
security.insecureAPI.rand ©
Warn on uses of inferior random number generating functions (only if arc4random function is available): drand48, erand48, jrand48, lcong48, lrand48, mrand48, nrand48, random, rand_r. -
security.insecureAPI.strcpy ©
Warn on uses of the strcpy and strcat functions. -
security.insecureAPI.vfork ©
Warn on uses of the ‘vfork’ function. -
security.insecureAPI.DeprecatedOrUnsafeBufferHandling ©
Warn on occurrences of unsafe or deprecated buffer handling functions, which now have a secure variant: sprintf, vsprintf, scanf, wscanf, fscanf, fwscanf, vscanf, vwscanf, vfscanf, vfwscanf, sscanf, swscanf, vsscanf, vswscanf, swprintf, snprintf, vswprintf, vsnprintf, memcpy, memmove, strncpy, strncat, memset
2.5 unix检查器
- unix.API ©
检查UNIX/POSIX函数调用:open, pthread_once, calloc, malloc, realloc, alloca。
- unix.Malloc ©
检查内存泄露,重复释放、释放后使用等内存代码缺陷。追踪被malloc()/free()管理的内存。
-
unix.Vfork ©
检查vfork是否合适使用。 -
unix.cstring.BadSizeArg ©
检查传递给C字符串函数的size参数的错误模式。使用-Wno-strncat-size
编译器选项屏蔽其他strncat-
相关的编译告警。 -
unix.cstring.NullArg ©
检查空指针作为参数传递给C字符串函数:strlen, strnlen, strcpy, strncpy, strcat, strncat, strcmp, strncmp, strcasecmp, strncasecmp, wcslen, wcsnlen。
3、Experimental Checkers 实验检查器
3.1 alpha.clone检查器
- alpha.clone.CloneChecker (C, C++, ObjC)
检查类似的重复代码块。
3.2 alpha.core检查器
简单看一个,其他更多检查器,可以自行访问官网文档https://clang.llvm.org/docs/analyzer/checkers.html#alpha-core。
- alpha.core.C11Lock
类似alpha.unix.PthreadLock,检查互斥锁的mtx_t mutexeslocking/unlocking的上锁和解锁。
老师这更新频率膜拜一波