检测内存泄露<------>通过asan的方式

1) 首先,我们看一下个asan_check.patch

复制代码
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1630200..fa00a93 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,6 +14,10 @@ IF(CPPBUILD_TARGET_ARCH STREQUAL "X86_64")
     ADD_DEFINITIONS( -DQUALIFICATION_TEST )
 ENDIF()

+ADD_COMPILE_OPTIONS( -fsanitize=address  -fno-stack-protector -fno-omit-frame-pointer -fno-var-tracking )
+ADD_LINK_OPTIONS( -fsanitize=address )
+LINK_LIBRARIES( asan )
+
 set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
 FILE(GLOB_RECURSE SRC ${PROJECT_SOURCE_DIR}/src/*.cpp)
 SET(TARGET_NAME sensevehicle)
diff --git a/demos/integration_test/CMakeLists.txt b/demos/integration_test/CMakeLists.txt
index bd589c0..ddcacd0 100644
--- a/demos/integration_test/CMakeLists.txt
+++ b/demos/integration_test/CMakeLists.txt
@@ -1,6 +1,10 @@
 cmake_minimum_required(VERSION 3.12)
 project(test C CXX)

+ADD_COMPILE_OPTIONS( -fsanitize=address  -fno-stack-protector -fno-omit-frame-pointer -fno-var-tracking )
+ADD_LINK_OPTIONS( -fsanitize=address )
+LINK_LIBRARIES( asan )
+
 SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG -std=c++11  -ffunction-sections -fdata-sections ")
 SET(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG -ffunction-sections -fdata-sections ")
 #set(CMAKE_SOURCE_DIR "/data1/luomincheng/A02/autovehicle")
diff --git a/samples_CAPI/CMakeLists.txt b/samples_CAPI/CMakeLists.txt
index d5c88bb..f30c7e9 100644
--- a/samples_CAPI/CMakeLists.txt
+++ b/samples_CAPI/CMakeLists.txt
@@ -14,6 +14,10 @@ SET(CMAKE_EXE_LINKER_FLAGS  -pie)

 PROJECT(vehicle_samples)

+ADD_COMPILE_OPTIONS( -g -fsanitize=address  -fno-stack-protector -fno-omit-frame-pointer -fno-var-tracking )
+ADD_LINK_OPTIONS( -fsanitize=address )
+LINK_LIBRARIES( asan )
+
 FILE(GLOB samples ${PROJECT_SOURCE_DIR}/*.cpp)
 message("PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
 message(STATUS ${samples})
复制代码

这个 patch 是修改 CMake 配置文件的三个不同模块,主要是为了启用 **AddressSanitizer** (ASan) 进行内存错误检查。具体的修改包括:

### 1. 启用 AddressSanitizer (ASan)
**AddressSanitizer** 是一个快速的内存错误检测工具,可以帮助开发人员检测到很多常见的内存问题,如越界访问、内存泄漏、使用已释放的内存等。

在 patch 中,`ADD_COMPILE_OPTIONS` 和 `ADD_LINK_OPTIONS` 用于将 ASan 相关的编译和链接选项添加到 CMake 构建过程中。

### 2. 具体修改的文件
#### a. **`CMakeLists.txt`(主项目根目录)**

在根目录的 `CMakeLists.txt` 中,添加了以下内容:

```cmake
ADD_COMPILE_OPTIONS( -fsanitize=address -fno-stack-protector -fno-omit-frame-pointer -fno-var-tracking )
ADD_LINK_OPTIONS( -fsanitize=address )
LINK_LIBRARIES( asan )
```

- `ADD_COMPILE_OPTIONS( -fsanitize=address ... )`:添加了编译时选项,启用了 AddressSanitizer,关闭了栈保护、去掉了帧指针优化等选项,以确保 ASan 的正常工作。
- `ADD_LINK_OPTIONS( -fsanitize=address )`:为链接器添加了 `-fsanitize=address` 选项,这样在程序链接时会链接 ASan 的相关库。
- `LINK_LIBRARIES( asan )`:链接 `asan` 库,确保 AddressSanitizer 能够正常工作。

#### b. **`demos/integration_test/CMakeLists.txt`**

在 `demos/integration_test/CMakeLists.txt` 文件中也做了类似的修改:

```cmake
ADD_COMPILE_OPTIONS( -fsanitize=address -fno-stack-protector -fno-omit-frame-pointer -fno-var-tracking )
ADD_LINK_OPTIONS( -fsanitize=address )
LINK_LIBRARIES( asan )
```

这些修改与根目录 `CMakeLists.txt` 中的修改相同,启用 AddressSanitizer,并链接 `asan` 库。这样,`integration_test` 模块中的代码也会启用 AddressSanitizer。

#### c. **`samples_CAPI/CMakeLists.txt`**

在 `samples_CAPI/CMakeLists.txt` 文件中,同样添加了这些选项:

```cmake
ADD_COMPILE_OPTIONS( -g -fsanitize=address -fno-stack-protector -fno-omit-frame-pointer -fno-var-tracking )
ADD_LINK_OPTIONS( -fsanitize=address )
LINK_LIBRARIES( asan )
```

这里的改动与上面两者类似,但是 `ADD_COMPILE_OPTIONS` 中额外增加了 `-g` 选项,表示启用调试符号生成,这对调试时查看 ASan 报告中的堆栈跟踪非常有帮助。

### 3. 解释各个编译选项

- `-fsanitize=address`:启用 AddressSanitizer 检查,主要用于检测内存错误。
- `-fno-stack-protector`:禁用栈保护,栈保护通常会与 AddressSanitizer 冲突,禁用它可以确保 ASan 正常工作。
- `-fno-omit-frame-pointer`:禁用帧指针优化。帧指针优化会移除函数的帧指针,这可能会影响 ASan 的错误检测,因此禁用它以确保 ASan 能正确报告错误。
- `-fno-var-tracking`:禁用变量追踪,变量追踪可能会影响 AddressSanitizer 的正确性,禁用它可以提高稳定性。
- `-g`:生成调试信息,方便在调试时查看详细的堆栈信息,通常与 `-fsanitize=address` 一起使用时非常有用。

### 4. 目标

这些更改的主要目标是:

1. 启用 AddressSanitizer 来检测和报告内存相关的错误,如越界访问、内存泄漏、双重释放等。
2. 在编译和链接时设置适当的选项,确保 AddressSanitizer 的正常工作。
3. 使得主项目、集成测试和示例项目都可以受益于 AddressSanitizer 的内存错误检测功能。

### 总结

这个 patch 的目的是在 CMake 构建过程中启用 AddressSanitizer,目的是在代码运行时检查和检测内存错误。通过对多个 CMake 配置文件的修改,确保了项目的多个模块(主项目、集成测试和示例项目)都启用了内存错误检查。

 

2) 当需要检测内存泄露时,只需要一条命令,加入编译

  git apply asan_check.patch

./scripts/build_noriker.sh linux x86_64 ppl build

git apply 是 Git 中用来应用补丁(patch)文件的命令。补丁文件通常是一些记录了源代码更改的文件,包含对代码库的修改(如添加、删除或更改文件的内容)。

  • asan_check.patch 是一个补丁文件,它记录了启用 AddressSanitizer(ASan)检查的相关代码更改,具体来说,它修改了 CMake 配置文件来启用 ASan 编译选项。git apply 命令将会把这个补丁应用到当前的 Git 工作区,即修改相应的源代码文件
  • git apply asan_check.patch 会将补丁文件中的更改(启用 AddressSanitizer)应用到代码中。
  • ./scripts/build_noriker.sh linux x86_64 ppl build 会执行构建操作,针对 Linux 系统、x86_64 架构进行构建,并可能与 ppl 模块或配置相关。

这样做的目的通常是:

  1. 应用 ASan 补丁,启用内存错误检测。
  2. 构建项目,确保新的修改和配置正确编译并且能运行。

这个流程通常用于调试和检查项目是否存在内存错误(比如越界、内存泄漏等),尤其是在使用 AddressSanitizer 的情况下。

 

3) 进一步,编译后,输出检测结果

export ASAN_OPTIONS=halt_on_error=0:use_sigaltstack=0:detect_leaks=1:malloc_context_size=15:log_path=asan.log:alloc_dealloc_mismatch=0

 ./samples_CAPI/bin/test_DMS samples_CAPI/asan_check_videos/DMS.mp4 30

这段命令的作用可以分为两部分:设置环境变量和执行一个二进制文件(`test_DMS`),并传递一些参数。让我们逐步解析这两部分内容。

### 1. 设置 `ASAN_OPTIONS` 环境变量

```bash
export ASAN_OPTIONS=halt_on_error=0:use_sigaltstack=0:detect_leaks=1:malloc_context_size=15:log_path=asan.log:alloc_dealloc_mismatch=0
```

这一行是设置 **AddressSanitizer (ASan)** 的选项。`ASAN_OPTIONS` 环境变量用来控制 ASan 的行为,具体的选项如下:

- **`halt_on_error=0`**:设置为 `0` 表示当检测到错误时,程序不会立即停止执行。默认情况下,ASan 在检测到内存错误时会中止程序的执行。将其设置为 `0` 可以让程序继续执行,直到结束。这对于调试和检查错误的多个实例非常有用。

- **`use_sigaltstack=0`**:设置为 `0` 表示禁用使用备用信号栈(signal alternate stack)。默认情况下,ASan 会使用备用信号栈来处理一些特殊的信号(例如,栈溢出错误)。禁用这个选项可能会影响一些高级的错误处理行为,但对于某些平台或用例可能更为合适。

- **`detect_leaks=1`**:设置为 `1` 启用内存泄漏检测。ASan 将追踪程序的内存分配和释放操作,报告未释放的内存(内存泄漏)。这是调试中非常有用的选项,帮助开发者检测内存泄漏问题。

- **`malloc_context_size=15`**:这个选项控制 malloc 等内存分配函数的堆栈跟踪深度。默认情况下,ASan 会记录内存分配时的调用栈,但栈的深度有限。设置为 `15` 表示记录的堆栈深度为 15 层,这有助于更好地定位问题。

- **`log_path=asan.log`**:设置为 `asan.log`,指定 ASan 的日志输出文件。ASan 会将内存错误和其他相关信息记录到这个日志文件中,便于调试和分析。

- **`alloc_dealloc_mismatch=0`**:设置为 `0` 表示禁用分配和释放不匹配的检测。如果设置为 `1`,ASan 会检测内存的分配和释放是否成对匹配。如果分配和释放不匹配,它会输出警告。

通过这些选项的配置,程序将在运行时启用 AddressSanitizer 来检测内存错误,并将结果输出到指定的日志文件(`asan.log`)。

### 2. 执行 `test_DMS` 程序

```bash
./samples_CAPI/bin/test_DMS samples_CAPI/asan_check_videos/DMS.mp4 30
```

这一部分执行了 `test_DMS` 二进制文件,并传递了两个参数:

- **`samples_CAPI/asan_check_videos/DMS.mp4`**:这是传递给 `test_DMS` 的第一个参数,它指定了输入的视频文件路径。这个路径指向一个名为 `DMS.mp4` 的视频文件。`test_DMS` 程序可能是用来处理或测试视频文件的(例如,进行某种处理或者对视频进行检测)。

- **`30`**:这是传递给 `test_DMS` 的第二个参数,可能表示程序的配置选项之一。具体来说,它可能是指示程序处理视频的时长(例如,30秒),或者某种其他的处理参数。具体含义需要根据 `test_DMS` 的实现来确定。

### 总结

- **`ASAN_OPTIONS`** 设置了 AddressSanitizer 的一些选项,启用了内存泄漏检测,指定了错误日志文件,并控制了程序在错误发生时的行为。
- **`./samples_CAPI/bin/test_DMS`** 是执行一个二进制程序,处理指定的视频文件(`DMS.mp4`),并传递了一个参数(`30`,可能是处理时间或其他选项)。

总的来说,这段命令的目的是通过启用 AddressSanitizer 来检测程序在处理视频文件时可能出现的内存问题,并将相关信息记录到日志文件中进行后续分析。

posted @   白伟碧一些小心得  阅读(343)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示