【发布时间】:2013-12-17 04:11:03
【问题描述】:
第一季度
在一些开源库中,有一种常见的模式来保存私有缓冲区:
/* ======== in modnamemapping.c ======== */
static char *private_buffer = NULL;
const char *getname( int id ) {
if ( !private_buffer )
private_buffer = (char *) malloc( 0x100 ); // in addition, the length may not
// a compile-period-constant, or
// here is some realloc() and the
// branch does not enter only once.
snprintf( private_buffer, 0x100, "NameOf%d", id );
return private_buffer;
}
// *NO* code to free private_buffer ...
据我所知,这应该会导致内存泄漏,是吗?
我只知道解决此问题的一种方法,即使用pthread_key 和pthread_once。但是有一些嵌入式环境没有它们的内置实现,这种方法对于非线程程序来说看起来微不足道且不漂亮。还有其他 simple 和 clean 选择来处理这个问题吗?
第二季度
libc 中有类似的行为。
我写了一个 libc 函数strftime() 的简单测试代码,这使得 valgrind 在我的OS X Mavericks 上报告一些肯定丢失。 (brew 中的编译器 apple-gcc42 版本 4.2.1-5666.3)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main( void ) {
char buf[0x40], *fmt = "%x %X";
time_t t1 = time( NULL );
struct tm t2;
int ret;
(void) localtime_r( &t1, &t2 );
ret = strftime( buf, sizeof(buf), fmt, &t2 );
printf( "strftime('%s', <now>) = %d: [%s]\n", fmt, ret, buf );
return 0;
}
绝对丢失的一个:
==46746== 2,242 (16 direct, 2,226 indirect) bytes in 1 blocks are definitely lost in loss record 83 of 87
==46746== at 0x70AB: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==46746== by 0x334FE6: _nc_table_new (in /usr/lib/system/libsystem_notify.dylib)
==46746== by 0x334A63: __token_table_add_block_invoke (in /usr/lib/system/libsystem_notify.dylib)
==46746== by 0xB62AC: _dispatch_client_callout (in /usr/lib/system/libdispatch.dylib)
==46746== by 0xB621B: dispatch_once_f (in /usr/lib/system/libdispatch.dylib)
==46746== by 0x3328A6: token_table_add (in /usr/lib/system/libsystem_notify.dylib)
==46746== by 0x3326B2: notify_register_check (in /usr/lib/system/libsystem_notify.dylib)
==46746== by 0x196AB5: notify_register_tz (in /usr/lib/system/libsystem_c.dylib)
==46746== by 0x1965EA: tzsetwall_basic (in /usr/lib/system/libsystem_c.dylib)
==46746== by 0x1967A7: _st_tzset_basic (in /usr/lib/system/libsystem_c.dylib)
==46746== by 0x198FAE: strftime_l (in /usr/lib/system/libsystem_c.dylib)
==46746== by 0x100000EB2: main (strftime.c:10)
总结:
==46746== LEAK SUMMARY:
==46746== definitely lost: 32 bytes in 2 blocks
==46746== indirectly lost: 4,298 bytes in 7 blocks
==46746== possibly lost: 10,808 bytes in 1 blocks
==46746== still reachable: 16,384 bytes in 1 blocks
==46746== suppressed: 25,272 bytes in 375 blocks
在程序退出之前是否应该调用 libc 中的 cleanup-strftime 函数?或者一个新的 libc 补丁?
【问题讨论】:
-
嘿,你是如何让 Valgrind 在小牛队工作的?
-
该方法在comment 中由nddrylliog 在brew valgrind issue 23660 中描述,基于Diego Giagio on bugs.kde.org 的实验补丁。您可能需要阅读这两个线程以使过程更清晰。
标签: c gcc memory-leaks osx-mavericks libc