From owner-freebsd-current@FreeBSD.ORG Sat Aug 2 05:21:51 2003 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 02B7937B401 for ; Sat, 2 Aug 2003 05:21:51 -0700 (PDT) Received: from mtiwmhc13.worldnet.att.net (mtiwmhc13.worldnet.att.net [204.127.131.117]) by mx1.FreeBSD.org (Postfix) with ESMTP id 19E5943FBD for ; Sat, 2 Aug 2003 05:21:50 -0700 (PDT) (envelope-from rtdean@cytherianage.net) Received: from mahasamatman.internal.cytherianage.net (96.washington-09rh15rt.dc.dial-access.att.net[12.91.120.96]) by mtiwmhc13.worldnet.att.net (mtiwmhc13) with SMTP id <2003080212214711300f1anue>; Sat, 2 Aug 2003 12:21:48 +0000 Received: (qmail 506 invoked from network); 2 Aug 2003 12:21:47 -0000 Received: from glyph.internal.cytherianage.net (HELO cytherianage.net) (192.168.177.42) by mahasamatman.internal.cytherianage.net with SMTP; 2 Aug 2003 12:21:47 -0000 Message-ID: <3F2BAC6B.3040606@cytherianage.net> Date: Sat, 02 Aug 2003 08:19:55 -0400 From: "Ryan T. Dean" User-Agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.5a) Gecko/20030730 X-Accept-Language: en-us, en MIME-Version: 1.0 To: freebsd-current@freebsd.org Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: vfprintf() has a 4096-byte memory leak? X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 02 Aug 2003 12:21:51 -0000 "Poul-Henning Kamp" wrote: > In message <3F2B9C59.3060209 at cytherianage.net >, "Ryan T. Dean" writes: > >/Hey all- /> >/ I was doing some app debugging tonight, and noticed what appears to /> >/be a memory leak in vfprintf(). /> > This is probably the buffer which stdio uses for all I/O. > > Try calling > setbuf(stdout, NULL); > setbuf(stderr, NULL); > > as the very first thing in your program, and you will probably see > that it does not allocate the 4k buffer, you may also be able to > measure the performance change due to this. > > In other words, what you see is perfectly normal, and to be expected, > but if it is a problem for you, the above is the workaround. Aha. setbuf(stdout, NULL); does prevent the buffer from being allocated. However, in the case of stdout and stderr, if you don't setbuf() it to null, a buffer is malloc'd. The corresponding free() is in fclose. So, if you [f]printf() to stdout/stderr, and fclose(stdout/stderr), you are fine. If, however, you don't know that buffers are being allocated for stdin/stdout and don't fclose() or setbuf() to NULL, a 4096-byte chunk of memory is allocated and never freed. For shits and giggles, I checked a DeadRat 8 box - no buffering by default. I guess the only reason I'm worried is the potential number of programs in the ports tree originally written on a system where stdout/stderr behave differently, or people (like myself) who didn't have a clue any sort of output buffering was enabled on stdout/stderr, and as a result have memory leaks. If the porter did their job, it shouldn't be an issue (was caught, patched, and the patch submitted upstream), but, then, we never know, right? I don't know. I'm tired and not thinking the straightest. I'd like to apologize for any incoherence in my thoughts. I appreciate the prompt reply. -Ryan T. Dean (Code tested below on FBSD) test1.c: #include int main (void) { printf("Test\n"); return 0; } test1 memory debug output: 1059825156: 1: *** alloc: at 'ra=0x2816ee86' for 4096 bytes, got '0x804b008|s1' 1059825156: 1: top 10 allocations: 1059825156: 1: total-size count in-use-size count source 1059825156: 1: 4096 1 4096 1 ra=0x2816ee86 1059825156: 1: 4096 1 4096 1 Total of 1 1059825156: 1: dumping not-freed pointers changed since 0: 1059825156: 1: not freed: '0x804b008|s1' (4096 bytes) from 'ra=0x2816ee86' 1059825156: 1: total-size count source 1059825156: 1: 4096 1 ra=0x2816ee86 1059825156: 1: 4096 1 Total of 1 1059825156: 1: unknown memory: 1 pointer, 4096 bytes test2.c: #include int main (void) { printf("Test\n"); fclose(stdout); return 0; } test2 memory debug output: 1059825216: 1: *** alloc: at 'ra=0x2816ee86' for 4096 bytes, got '0x804b008|s1' 1059825216: 2: *** free: at 'ra=0x2815c431' pnt '0x804b008|s2': size 4096, alloced at 'ra=0x2816ee86' 1059825216: 2: top 10 allocations: 1059825216: 2: total-size count in-use-size count source 1059825216: 2: 4096 1 0 0 ra=0x2816ee86 1059825216: 2: 4096 1 0 0 Total of 1 1059825216: 2: dumping not-freed pointers changed since 0: 1059825216: 2: memory table is empty test3.c: #include int main (void) { setbuf(stdout, NULL); printf("Test\n"); return 0; } test3 memory debug output: (no output generated)