本主题说明如何使用 C++test 执行运行时错误检测。章节目录:
运行时错误检测概要
C++test 的运行时错误检测使团队能够在单元或应用程序级别自动识别严重的运行时缺陷,如内存泄漏、空指针、未初始化内存和缓冲区溢出。 它既适用于企业开发,也适用于嵌入式开发。
这种能力的可适应性使团队在使用非标准内存分配模型(例如,使用嵌入式系统)时也能利用运行时内存分析。由于用于该分析的插桩是轻量级插桩,因此可以在目标板、模拟器或主机上进行嵌入式测试。
报告收集的问题时包含有助于理解和修复问题的详细信息(包括内存块大小、数组索引、分配/释放堆栈跟踪等)跟踪覆盖率指标,帮助您衡量和扩大测试工作的范围。
在应用程序级执行运行时错误检测
对应用程序运行执行运行时错误检测的步骤:
运行 Application Monitoring 分组中的一个内建配置(例如,Application Monitoring> Build and Run Application with Memory Monitoring)。这些配置在 Application Monitoring 分组中有所说明。
C++test 将准备并运行一个应用程序可执行文件的插桩版本。根据选择的配置,C++test 将报告在应用程序执行期间发现的覆盖率统计数据和/或内存错误。
重要说明
对于可执行文件中内建的项目,您可以通过运行时错误检测来监控应用程序运行。要监控库项目,您需要在项目中添加带有 'main()' 函数定义的附加代码(模拟使用被测库的某些场景)来用于 C++test。例如,可以将这样的 'main()' 函数与 #ifdef PARASOFT_CPPTEST
保护一起添加到被测库的某个源文件中。
在单元测试执行期间执行运行时错误检测
在单元测试执行期间执行运行时错误检测的步骤:
- 运行“Unit Testing> Run Unit Tests with Memory Monitoring”测试配置。
C++test 将生成一个启用了运行时内存分析功能的测试可执行文件,然后执行测试。测试执行完成后,C++test 会将发现的内存问题与常规单元测试任务一同报告。
每个运行时错误检测问题都会在以下位置报告为特定违规(包含消息、位置和堆栈跟踪):
- GUI 中的 C++test 任务视图。
- GUI 中的代码编辑器。
- C++test 控制台(GUI 和 CLI 执行)。
- 测试执行后生成的报告。
抑制运行时错误检测违规
可以像抑制静态分析违规一样抑制运行时错误检测违规:在 GUI 或源代码中抑制(// parasoft-suppress <ruleid> ["<reason>"]
)。
有关详细说明,请参阅抑制可接受违规的报告。
自定义运行时错误检测选项
您可以通过修改测试配置管理器执行选项卡中的选项来自定义运行时错误检测。
在执行> 常规选项卡中,您可以控制以下选项:
- 单元测试或应用程序监测分析模式:控制在执行单元测试时是否应执行运行时错误检测,或者是否应构建和执行一个独立的应用程序(没有测试用例的情况下)。
- 对于应用程序监测模式,您可以(可选)指定应用程序二进制位置/名称(Test application binary)以及指定执行命令行(Application command line)。
- 测试执行流程:
- 在应用程序监测模式下,可以使用 Build application executable or Build and run application executable 测试执行流程。
- 在单元测试模式下,可以使用标准或自定义单元测试执行流程。详细信息请参阅自定义测试执行流程。
- 插桩模式:
- 在应用程序监测模式下,可以使用应用完全监测、应用程序内存监测或应用程序覆盖率监测。
- 在单元测试模式下,可以使用带有内存监测的完全运行时。
在执行> 运行时选项卡中,可以控制以下选项:
- 测试可执行程序运行目录:对于单元测试和应用程序监测模式,这决定了创建和执行测试可执行程序的目录。如果在测试用例源或原始代码中使用了相对路径,C++test 将在该目录中搜索引用的文件。
运行时错误检测规则
C++test 提供了以下运行时错误检测“规则”,可在被测代码中发现内存相关的问题:
规则标识符 | 说明 |
---|---|
RUN-MEM-DANG | 不要使用悬空指针访问内存 此规则查找与使用指向已释放内存的指针相关的问题。 |
RUN-MEM-WILD | 不要使用野指针访问内存 此规则查找与使用不指向有效内存缓冲区的指针相关的问题。 |
RUN-MEM-NULL | 不要使用空指针访问内存 此规则查找与使用空指针相关的问题。 |
RUN-MEM-RANGE | 不要使用超出范围的指针访问内存 此规则查找与访问超出范围的缓冲区相关的问题(例如,访问只有 9 个元素的缓冲区中第 10 个元素)。 |
RUN-MEM-UNINIT | 不要读取未初始化的内存 此规则查找与读取已分配(但未初始化)内存相关的问题。 |
RUN-MEM-FREEDANG | 不要对悬空指针使用 free 此规则查找与尝试对已释放的内存指针使用 free 相关的问题。 |
RUN-MEM-FREEIL | 不要对非法指针使用 free 此规则查找与尝试对不指向由 malloc 分配的有效内存块指针使用 free 相关的问题。 |
RUN-MEM-FREELOC | 不要对本地内存指针使用 free 此规则查找与尝试对指向本地内存块的指针使用 free 相关的问题。 |
RUN-MEM-FREEGLOB | 不要对全局内存指针使用 free 此规则查找与尝试对指向全局内存块的指针使用 free 相关的问题。 |
RUN-MEM-FREENULL | 不要对空指针使用 free 此规则查找与尝试对空指针使用 free 相关的问题。 |
RUN-MEM-MAZERO | 不要使用大小为 0 的 malloc 此规则查找与使用 malloc 分配大小为零的缓冲区相关的问题。 |
RUN-MEM-CAZEROELEM | 不要使用元素数为 0 的 calloc 此规则查找与使用 calloc 分配零元素缓冲区相关的问题。 |
RUN-MEM-CAZEROSIZE | 不要使用元素大小为 0 的calloc 此规则查找与使用 calloc 分配大小为零的元素的缓冲区相关的问题。 |
RUN-MEM-RAILL | 不要对非法指针使用 realloc 此规则查找与对不指向由 malloc 分配的有效内存块指针使用 realloc 相关的问题。 |
RUN-MEM-RALOC | 不要对本地内存指针使用 realloc 此规则查找与对指向本地内存块的指针使用 realloc 相关的问题。 |
RUN-MEM-RAGLOB | 不要对全局内存指针使用 realloc 此规则查找与对指向全局内存块的指针使用 realloc 相关的问题。 |
RUN-MEM-RAZERO | 不要使用新的大小为 0 的 realloc 此规则查找与使用 realloc 分配大小为零的缓冲区相关的问题。 |
RUN-MEM-LEAK | 避免内存泄露 此规则查找内存泄漏问题。当指向用 malloc/realloc/calloc 分配的内存的指针丢失时,将报告问题。 |
RUN-MEM-CORRUPT | 避免内存损坏 这条规则查找内存损坏问题。当使用 malloc/realloc/calloc 分配的内存块在释放过程中被意外覆盖时,将报告问题。 |
运行时错误检测测试配置
有关可用测试配置的说明,请参阅内建测试配置。
如果您想要确认是否可以开始进行测试,我们建议您使用“Build Application with...”测试配置。如果构建的应用程序将在外部运行(例如,用于嵌入式测试),也可以使用这些测试配置。在这种情况下,完整的流程由构建、部署/运行(手动完成)和“读取日志”步骤组成。
当您想让 C++test 使用测试配置中指定的命令行构建和执行被测应用程序时,应使用“Build and Run Application with...”测试配置。
更具体地说:
- 当您想让 C++test 对被测应用程序执行运行时错误检测时,应使用“...Memory Monitoring”配置。
- 当您想让 C++test 从被测应用程序运行中收集覆盖率信息时,应使用“...Coverage Monitoring”配置。
- 当您想要执行运行时错误检测并收集覆盖率信息时,应使用“...Full Monitoring”配置。
已知的运行时错误检测限制
- 仅监测 C 语言风格的动态内存分配(使用 malloc()、calloc()、realloc())。
- 仅监测 C 语言风格的动态内存释放(使用 free())。
- 仅监测全局数组(不监测函数中定义的静态数组)。
- 内存相关的操作必须直接在被测试和插桩的编译单元中进行,便于进行监测。
- 在 C++ 模板中执行的内存相关的操作不受监控,可能会影响结果。
- 在外部库中执行的内存相关的操作不受监控,可能会影响结果。
- 默认情况下,内存泄漏(RUN-MEM-LEAK)仅在应用程序监测模式下报告。
- 不监测向量数据类型操作。