【问题标题】:valgrind memcheck reports false positive?valgrind memcheck 报告误报?
【发布时间】:2023-12-02 11:27:01
【问题描述】:

这是我的代码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char buf1[100];
char buf2[100];

int main()
{
    char **p = (char**)(buf1+sizeof(long));
    char **q = (char**)(buf2+1);
    *p = (char*)malloc(100);
    *q = (char*)malloc(100);

    strcpy(*p, "xxxx");
    strcpy(*q, "zzzz");

    printf("p:%s   q:%s\n", *p, *q);
    return 0;
}

我使用 gcc 编译了代码,然后像这样运行 valgrind-3.6.1

valgrind --leak-check=full --log-file=test.log  --show-reachable=yes  ~/a.out 

valgrind 给了我下面的日志

==20768== Memcheck, a memory error detector
==20768== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==20768== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==20768== Command: /home/zxin11/a.out
==20768== Parent PID: 12686
==20768== 
==20768== 
==20768== HEAP SUMMARY:
==20768==     in use at exit: 200 bytes in 2 blocks
==20768==   total heap usage: 2 allocs, 0 frees, 200 bytes allocated
==20768== 
==20768== 100 bytes in 1 blocks are still reachable in loss record 1 of 2
==20768==    at 0x4C2488B: malloc (vg_replace_malloc.c:236)
==20768==    by 0x4005FD: main (test2.c:12)
==20768== 
==20768== 100 bytes in 1 blocks are definitely lost in loss record 2 of 2
==20768==    at 0x4C2488B: malloc (vg_replace_malloc.c:236)
==20768==    by 0x400611: main (test2.c:13)
==20768== 
==20768== LEAK SUMMARY:
==20768==    definitely lost: 100 bytes in 1 blocks
==20768==    indirectly lost: 0 bytes in 0 blocks
==20768==      possibly lost: 0 bytes in 0 blocks
==20768==    still reachable: 100 bytes in 1 blocks
==20768==         suppressed: 0 bytes in 0 blocks
==20768== 
==20768== For counts of detected and suppressed errors, rerun with: -v
==20768== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 3 from 3)

为什么第一个 malloc 仍然可以访问,而第二个 malloc 肯定丢失了? 可能是对齐的问题,不能把malloced内存的地址放到一个未对齐的变量中,如果是这样,我怎么能压制这种正面的报告呢? 很想你。

【问题讨论】:

    标签: memory-leaks alignment valgrind


    【解决方案1】:

    来自memcheck manual(强调我的):

    如果--leak-check 设置得当,对于每个剩余的块,Memcheck 确定该块是否可以从根集中的指针访问。根集由 (a) 所有线程的通用寄存器和 (b) 已初始化、对齐、指针大小的数据字在可访问的客户端内存(包括堆栈)中组成。

    所以你关于对齐的猜想是正确的。不幸的是,强有力地抑制此类警告的最佳方法可能只是在退出程序之前将任何此类已知值复制到对齐的位置(大概此代码是您实际应用程序的模型,它对您有某种意义存储未对齐的指针)。

    您也可以尝试writing or generating a suppression file--gen-suppressions=yes。但是,如果您的应用程序是不确定的,或者您使用不同的输入数据运行它,那么这种方法很快就会变得很烦人。

    【讨论】: