动态代码检查是发生在程序执行过程中的一种检测,检测的内容通常有,
- 内存泄漏。如:申请的内存没有释放
- 访问未初始化的内存。如:读取一片没有初始化过的内存
- 线程并发问题。如:多个线程并发访问同一片内存,一个读一个写
- 不可预知的行为。如:除0操作
- ...
在引入动态代码检查之前,你需要知道,
- 会拖慢程序的执行
- 检查只发生在能够执行到的代码
下面介绍常见的动态代码检查工具,
Google sanitizers
谷歌推出的开源动态代码检查工具。可以检查很多种的问题,下面分别介绍,
AddressSanitizer (ASan)
检测内存使用情况,包含,
- Heap-, stack-, and global buffer overflow
- Use-after-free (dangling pointer dereference)
- Use-after-scope -fsanitize-address-use-after-scope
- Use-after-return (pass detect_stack_use_after_return=1 to ASAN_OPTIONS)
- Double free, invalid free
- Initialization order bugs
举例,
int global_array[100] = {-1};
int main(int argc, char **argv) {
return global_array[argc + 100]; // global buffer overflow
}
LeakSanitizer (LSan)
检测内存泄漏。
举例,
int main(){
int *x = new int(10);
return 0;
}
ThreadSanitizer (TSan)
检测数据冲突。
举例,
#include <pthread.h>
#include <stdio.h>
int Global;
void *Thread1(void *x) {
Global++;
return NULL;
}
void *Thread2(void *x) {
Global--;
return NULL;
}
int main() {
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
pthread_join(t[0], NULL);
pthread_join(t[1], NULL);
}
UndefinedBehaviorSanitizer (UBSsan)
检测诸如除零、使用空指针、使用没有初始化的非静态变量等可能导致不确定行为的问题。
举例,
int main(){
int i = 2048;
i <<= 28;
return 0;
}
MemorySanitizer (MSan)
检测读取未初始化的内存的操作。
举例,
int main(int argc, char** argv) {
int* a = new int[10];
a[5] = 0;
if (a[argc])
std::cout << a[3];
return 0;
}
Valgrind memcheck
Valgrind是检测C/C++代码中内存相关问题的一个工具。检测的内容有,
- 内存泄漏
- 错误地释放内存
- 读取未初始化的内存
Code coverage
Code coverage可以统计程序执行过程中所执行的代码行数以及每一行代码执行的次数。
网友评论