简体   繁体   English

Valgrind和“#pragma pack(2)”

[英]Valgrind and “#pragma pack(2)”

I've got a problem using valgrind. 我使用valgrind时遇到了问题。 In my project all structures are surrounded by #pragma pack(2) to reduce memory usage. 在我的项目中,所有结构都被#pragma pack(2)包围,以减少内存使用。

Now, allocating memory to a pointer within a structure leads to a valgrind error, eg: 14 bytes in 7 blocks are definitely lost in loss record 2 of 3. 现在,将内存分配给结构内的指针会导致valgrind错误,例如:7个块中的14个字节肯定会在3个丢失记录中丢失。

EDIT: I was not precise enough. 编辑:我不够精确。 Sure, there is a memory leak as I never call free. 当然,有一个内存泄漏,因为我从来没有免费。 But the problem is, that valgrind says the memory is definetly lost. 但问题是,valgrind说内存肯定会丢失。 This it not the case, since param_info is static. 事实并非如此,因为param_info是静态的。

So why does valgrind says definitely lost and not still reachable? 那么为什么valgrind肯定会丢失并且仍然无法访问? If I remove the pragma directives the output is as expected. 如果我删除pragma指令,则输出符合预期。

Is this to be expected? 这是预期的吗? And if so, can anybody please explain why? 如果是这样,有人可以解释原因吗?

Here is a minimal example to reproduce the error: 这是重现错误的最小示例:

#include <stdlib.h>

#pragma pack(push)
#pragma pack(2)

struct param_ref
    {
    short  *p;
    short   max_p;
    };

#pragma pack(pop)

int main()
{
    static struct param_ref    *param_info = NULL;
    static short                param_max  = 0;

    int i;

    if (param_info == NULL)
        {
        param_max  = 10;
        param_info = malloc(sizeof (struct param_ref) * param_max);

        for (i = 0; i < param_max; i++)
            {
            param_info[i].p     = malloc(sizeof (short));
            param_info[i].max_p = 1;
            }
        }

    return 0;
}

And the valgrind output: 和valgrind输出:

xxx@homer:~/val$ valgrind --leak-check=full ./a.out
==4156== Memcheck, a memory error detector
==4156== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4156== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==4156== Command: ./a.out
==4156== 
==4156== 
==4156== HEAP SUMMARY:
==4156==     in use at exit: 120 bytes in 11 blocks
==4156==   total heap usage: 11 allocs, 0 frees, 120 bytes allocated
==4156== 
==4156== 14 bytes in 7 blocks are definitely lost in loss record 2 of 3
==4156==    at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4156==    by 0x4005AF: main (in /home/xxx/val/a.out)
==4156== 
==4156== LEAK SUMMARY:
==4156==    definitely lost: 14 bytes in 7 blocks
==4156==    indirectly lost: 0 bytes in 0 blocks
==4156==      possibly lost: 0 bytes in 0 blocks
==4156==    still reachable: 106 bytes in 4 blocks
==4156==         suppressed: 0 bytes in 0 blocks
==4156== Reachable blocks (those to which a pointer was found) are not shown.
==4156== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==4156== 
==4156== For counts of detected and suppressed errors, rerun with: -v
==4156== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

EDIT2: Output of valgrind without pragma directives: EDIT2:没有pragma指令的valgrind输出:

xxx@homer:~/val$ valgrind --leak-check=full ./a.out
==5374== Memcheck, a memory error detector
==5374== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==5374== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==5374== Command: ./a.out
==5374== 
==5374== 
==5374== HEAP SUMMARY:
==5374==     in use at exit: 180 bytes in 11 blocks
==5374==   total heap usage: 11 allocs, 0 frees, 180 bytes allocated
==5374== 
==5374== LEAK SUMMARY:
==5374==    definitely lost: 0 bytes in 0 blocks
==5374==    indirectly lost: 0 bytes in 0 blocks
==5374==      possibly lost: 0 bytes in 0 blocks
==5374==    still reachable: 180 bytes in 11 blocks
==5374==         suppressed: 0 bytes in 0 blocks
==5374== Reachable blocks (those to which a pointer was found) are not shown.
==5374== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==5374== 
==5374== For counts of detected and suppressed errors, rerun with: -v
==5374== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Some pointers to the memory are not properly aligned for valgrind to find them due to the packing hence valgrind reports them as definitely lost. 一些指向内存的指针没有正确对齐valgrind找到它们因为打包因此valgrind报告它们肯定丢失了。 It seems it has no option for this like LeakSanitizer : LSAN_OPTIONS=use_unaligned=1 似乎它没有像LeakSanitizer那样的选项LSAN_OPTIONS=use_unaligned=1

use_unaligned : If 0, LSan will only consider properly aligned 8-byte patterns when looking for pointers. use_unaligned:如果为0,则LSan在查找指针时仅考虑正确对齐的8字节模式。 Set to 1 to include unaligned patterns. 设置为1以包含未对齐的图案。 This refers to the pointer itself, not the memory being pointed at. 这指的是指针本身,而不是指向的内存。

$ gcc so.c -fsanitize=address -g
$ ./a.out

=================================================================
==4943==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 14 byte(s) in 7 object(s) allocated from:
    #0 0x7fe18898ba0a in malloc (/lib64/libasan.so.2+0x98a0a)
    #1 0x4008d2 in main /home/m/so.c:28
    #2 0x7fe18855378f in __libc_start_main (/lib64/libc.so.6+0x2078f)

SUMMARY: AddressSanitizer: 14 byte(s) leaked in 7 allocation(s).
$ LSAN_OPTIONS=use_unaligned=1 ./a.out
$

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM