Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Valgrind and "#pragma pack(2)"

I've got a problem using valgrind. In my project all structures are surrounded by #pragma pack(2) to reduce memory usage.

Now, allocating memory to a pointer within a structure leads to a valgrind error, e. g.: 14 bytes in 7 blocks are definitely lost in loss record 2 of 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. This it not the case, since param_info is static.

So why does valgrind says definitely lost and not still reachable? If I remove the pragma directives the output is as expected.

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:

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:

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)
like image 477
RedPepper Avatar asked Feb 20 '26 00:02

RedPepper


1 Answers

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. It seems it has no option for this like LeakSanitizer: LSAN_OPTIONS=use_unaligned=1

use_unaligned : If 0, LSan will only consider properly aligned 8-byte patterns when looking for pointers. Set to 1 to include unaligned patterns. 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
$
like image 120
4566976 Avatar answered Feb 21 '26 14:02

4566976



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!