getpwnam 中的内存泄漏是不是有修复或解决方法?
Posted
技术标签:
【中文标题】getpwnam 中的内存泄漏是不是有修复或解决方法?【英文标题】:Is there a fix or a workaround for the memory leak in getpwnam?getpwnam 中的内存泄漏是否有修复或解决方法? 【发布时间】:2008-10-09 18:32:50 【问题描述】:是否有针对 getpwnam 中的内存泄漏的修复或解决方法?
【问题讨论】:
【参考方案1】:getpwnam()
不会遭受内存泄漏。实际上,后续调用将覆盖其静态内部缓冲区。
这类函数是不可重入,因此非线程安全。 Paul 建议使用getpwnam_r()
,它是可重入版本,可以安全地用于多线程上下文。
也就是说,内存泄漏是由那些通过malloc()
分配内存的系统调用引起的,一旦返回的数据被使用,应用程序就对free()
的内存负责。
在这些情况下,建议使用 RAII 习惯用法,以免忘记释放分配的内存——请参阅异常安全。 std::tr1::shared_ptr<>
也是一种可行的方法:对于 shared_ptr,当 shared_ptr 超出范围时,必须为 free()
原始指针提供自定义删除器。
从这个角度来看,一些危险的函数是scandir()
、asprintf()
、vasprintf()
等。
【讨论】:
哦,好答案。如果我可以将“已接受的答案”转给您,我会的。 答案在概念上是正确的,但不是 getpwnam 或 getpwnam_r 发生的情况。在内部,libc(不是用户代码)动态分配 nss 数据,这些数据永远不会被释放。没有任何方法可以在用户代码中使用任何习语来解决这个问题,因为问题在 libc 内部。见:sourceware.org/bugzilla/show_bug.cgi?id=2314【参考方案2】:使用 getpwnam_r。
【讨论】:
【参考方案3】:我认为没有解决方法。上面的答案没有帮助,请参阅:
daniel@senap:~/dev/tryouts$ uname -a
Linux senap 3.2.0-24-generic #39-Ubuntu SMP Mon May 21 16:52:17 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
daniel@senap:~/dev/tryouts$ cat getpwnam-leak.c
#include <sys/types.h>
#include <pwd.h>
extern void __libc_freeres(void);
int main()
char buf[1024];
struct passwd pw, *result;
getpwnam_r("root", &pw, buf, sizeof(buf), &result);
__libc_freeres();
daniel@senap:~/dev/tryouts$ valgrind --leak-check=full ./getpwnam-leak
==6951== Memcheck, a memory error detector
==6951== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==6951== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==6951== Command: ./getpwnam-leak
==6951==
==6951==
==6951== HEAP SUMMARY:
==6951== in use at exit: 300 bytes in 11 blocks
==6951== total heap usage: 69 allocs, 58 frees, 9,234 bytes allocated
==6951==
==6951== 300 (60 direct, 240 indirect) bytes in 1 blocks are definitely lost in loss record 11 of 11
==6951== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6951== by 0x4F35D94: nss_parse_service_list (nsswitch.c:678)
==6951== by 0x4F36855: __nss_database_lookup (nsswitch.c:175)
==6951== by 0x55F32A4: ???
==6951== by 0x4EEF1AC: getpwnam_r@@GLIBC_2.2.5 (getXXbyYY_r.c:256)
==6951== by 0x400607: main (in /home/daniel/dev/tryouts/getpwnam-leak)
==6951==
==6951== LEAK SUMMARY:
==6951== definitely lost: 60 bytes in 1 blocks
==6951== indirectly lost: 240 bytes in 10 blocks
==6951== possibly lost: 0 bytes in 0 blocks
==6951== still reachable: 0 bytes in 0 blocks
==6951== suppressed: 0 bytes in 0 blocks
==6951==
==6951== For counts of detected and suppressed errors, rerun with: -v
==6951== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
daniel@senap:~/dev/tryouts$
【讨论】:
【参考方案4】:要解决这个问题,只需这样做:
sudo sed -i s/compat/files/g /etc/nsswitch.conf
这似乎是由于 libnss_compat 中的错误引起的。更多信息请访问bugs.debian.org。
【讨论】:
以上是关于getpwnam 中的内存泄漏是不是有修复或解决方法?的主要内容,如果未能解决你的问题,请参考以下文章