在 Linux 中的 getgrnam 和 getgrnam_r 中观察到内存泄漏

问题描述 投票:0回答:1

我正在尝试使用一些基本的 C 代码检索 linux 组,但是 getgrnam 和 getgrnam_r 都遇到内存泄漏。仅当

/etc/group
中缺少 linux 组时才会发生内存泄漏。

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <grp.h>
#include <pwd.h>

static char* group_name = "dummy";

static void test_getgrnam_r(void) {
    struct group grp;
    struct group* group = NULL;
    int bufsize = 0;
    int retval = -1;
    char* buf = NULL;

    bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
    if(bufsize == -1) {
        bufsize = 16384;
    }

    buf = calloc(1, bufsize);
    retval = getgrnam_r(group_name, &grp, buf, bufsize, &group);
    printf("retval = %d\n", retval);

    free(buf);
    free(group);
}

static void test_getgrnam(void) {
    struct group* group = getgrnam(group_name);
}

int main(void) {
    test_getgrnam();
    //test_getgrnam_r();
}

可以使用简单的 gcc 命令来编译此代码:

gcc main.c -o out

并且可以使用 valgrind 运行它来显示内存泄漏:

valgrind --leak-check=full --show-leak-kinds=all ./out
==2255356== Memcheck, a memory error detector
==2255356== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2255356== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==2255356== Command: ./out
==2255356== 
==2255356== 
==2255356== HEAP SUMMARY:
==2255356==     in use at exit: 5,177 bytes in 13 blocks
==2255356==   total heap usage: 77 allocs, 64 frees, 19,669 bytes allocated
==2255356== 
==2255356== 46 bytes in 1 blocks are still reachable in loss record 1 of 8
==2255356==    at 0x483877F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==2255356==    by 0x401C26A: strdup (strdup.c:42)
==2255356==    by 0x40172FB: _dl_load_cache_lookup (dl-cache.c:338)
==2255356==    by 0x4009776: _dl_map_object (dl-load.c:2102)
==2255356==    by 0x4013D41: dl_open_worker (dl-open.c:513)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356==    by 0x40138F9: _dl_open (dl-open.c:837)
==2255356==    by 0x4986FCC: do_dlopen (dl-libc.c:96)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356==    by 0x4987C0E: _dl_catch_error (dl-error-skeleton.c:227)
==2255356==    by 0x49870A6: dlerror_run (dl-libc.c:46)
==2255356==    by 0x4987135: __libc_dlopen_mode (dl-libc.c:195)
==2255356== 
==2255356== 46 bytes in 1 blocks are still reachable in loss record 2 of 8
==2255356==    at 0x483877F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==2255356==    by 0x400BFB7: _dl_new_object (dl-object.c:196)
==2255356==    by 0x4007255: _dl_map_object_from_fd (dl-load.c:997)
==2255356==    by 0x4009274: _dl_map_object (dl-load.c:2236)
==2255356==    by 0x4013D41: dl_open_worker (dl-open.c:513)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356==    by 0x40138F9: _dl_open (dl-open.c:837)
==2255356==    by 0x4986FCC: do_dlopen (dl-libc.c:96)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356==    by 0x4987C0E: _dl_catch_error (dl-error-skeleton.c:227)
==2255356==    by 0x49870A6: dlerror_run (dl-libc.c:46)
==2255356==    by 0x4987135: __libc_dlopen_mode (dl-libc.c:195)
==2255356== 
==2255356== 71 bytes in 2 blocks are still reachable in loss record 4 of 8
==2255356==    at 0x483877F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==2255356==    by 0x401C26A: strdup (strdup.c:42)
==2255356==    by 0x40172FB: _dl_load_cache_lookup (dl-cache.c:338)
==2255356==    by 0x4009776: _dl_map_object (dl-load.c:2102)
==2255356==    by 0x400DDC0: openaux (dl-deps.c:64)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356==    by 0x400E138: _dl_map_object_deps (dl-deps.c:248)
==2255356==    by 0x4013DAA: dl_open_worker (dl-open.c:571)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356==    by 0x40138F9: _dl_open (dl-open.c:837)
==2255356==    by 0x4986FCC: do_dlopen (dl-libc.c:96)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356== 
==2255356== 71 bytes in 2 blocks are still reachable in loss record 5 of 8
==2255356==    at 0x483877F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==2255356==    by 0x400BFB7: _dl_new_object (dl-object.c:196)
==2255356==    by 0x4007255: _dl_map_object_from_fd (dl-load.c:997)
==2255356==    by 0x4009274: _dl_map_object (dl-load.c:2236)
==2255356==    by 0x400DDC0: openaux (dl-deps.c:64)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356==    by 0x400E138: _dl_map_object_deps (dl-deps.c:248)
==2255356==    by 0x4013DAA: dl_open_worker (dl-open.c:571)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356==    by 0x40138F9: _dl_open (dl-open.c:837)
==2255356==    by 0x4986FCC: do_dlopen (dl-libc.c:96)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356== 
==2255356== 1,204 bytes in 1 blocks are still reachable in loss record 6 of 8
==2255356==    at 0x483AB65: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==2255356==    by 0x400BCDF: _dl_new_object (dl-object.c:89)
==2255356==    by 0x4007255: _dl_map_object_from_fd (dl-load.c:997)
==2255356==    by 0x4009274: _dl_map_object (dl-load.c:2236)
==2255356==    by 0x4013D41: dl_open_worker (dl-open.c:513)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356==    by 0x40138F9: _dl_open (dl-open.c:837)
==2255356==    by 0x4986FCC: do_dlopen (dl-libc.c:96)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356==    by 0x4987C0E: _dl_catch_error (dl-error-skeleton.c:227)
==2255356==    by 0x49870A6: dlerror_run (dl-libc.c:46)
==2255356==    by 0x4987135: __libc_dlopen_mode (dl-libc.c:195)
==2255356== 
==2255356== 1,296 bytes in 3 blocks are still reachable in loss record 7 of 8
==2255356==    at 0x483AB65: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==2255356==    by 0x40116B6: _dl_check_map_versions (dl-version.c:274)
==2255356==    by 0x4013DF5: dl_open_worker (dl-open.c:577)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356==    by 0x40138F9: _dl_open (dl-open.c:837)
==2255356==    by 0x4986FCC: do_dlopen (dl-libc.c:96)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356==    by 0x4987C0E: _dl_catch_error (dl-error-skeleton.c:227)
==2255356==    by 0x49870A6: dlerror_run (dl-libc.c:46)
==2255356==    by 0x4987135: __libc_dlopen_mode (dl-libc.c:195)
==2255356==    by 0x496F355: nss_load_library (nsswitch.c:359)
==2255356==    by 0x496FBE8: __nss_lookup_function (nsswitch.c:467)
==2255356== 
==2255356== 2,395 bytes in 2 blocks are still reachable in loss record 8 of 8
==2255356==    at 0x483AB65: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==2255356==    by 0x400BCDF: _dl_new_object (dl-object.c:89)
==2255356==    by 0x4007255: _dl_map_object_from_fd (dl-load.c:997)
==2255356==    by 0x4009274: _dl_map_object (dl-load.c:2236)
==2255356==    by 0x400DDC0: openaux (dl-deps.c:64)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356==    by 0x400E138: _dl_map_object_deps (dl-deps.c:248)
==2255356==    by 0x4013DAA: dl_open_worker (dl-open.c:571)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356==    by 0x40138F9: _dl_open (dl-open.c:837)
==2255356==    by 0x4986FCC: do_dlopen (dl-libc.c:96)
==2255356==    by 0x4987B4F: _dl_catch_exception (dl-error-skeleton.c:208)
==2255356== 
==2255356== LEAK SUMMARY:
==2255356==    definitely lost: 0 bytes in 0 blocks
==2255356==    indirectly lost: 0 bytes in 0 blocks
==2255356==      possibly lost: 0 bytes in 0 blocks
==2255356==    still reachable: 5,129 bytes in 12 blocks
==2255356==         suppressed: 48 bytes in 1 blocks
==2255356== 
==2255356== For lists of detected and suppressed errors, rerun with: -s
==2255356== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

我发现了一些类似的帖子,但似乎都没有解决此问题的方法。

其中一些人建议使用

extern void __libc_freeres (void);

但是调用这个函数似乎也没有帮助。根据 valgrind 文档,我认为运行 valgrind 时已经默认调用此函数。

--run-libc-freeres= [默认值:是]

https://valgrind.org/docs/manual/manual-core.html

这是否意味着我遇到了内存泄漏问题,或者是否有我尚未找到的解决方案?如果我可以提供额外信息,请告诉我。我试图让我的示例尽可能简单。

c linux gcc memory-leaks valgrind
1个回答
0
投票

尝试将以下内容放入文件中

{
   _dl_new_object
   Memcheck:Leak
   match-leak-kinds: reachable
   ...
   fun:_dl_open
}

例如,dlopen.supp

然后运行

valgrind --leak-check=full  --show-leak-kinds=all --suppressions=dlopen.supp

不同的 Linux 发行版之间存在一些差异,但上述抑制是广泛的,应该涵盖所有情况。

© www.soinside.com 2019 - 2024. All rights reserved.