From owner-freebsd-current@FreeBSD.ORG Sat Aug 2 13:51:05 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 912E637B401 for ; Sat, 2 Aug 2003 13:51:05 -0700 (PDT) Received: from dan.emsphone.com (dan.emsphone.com [199.67.51.101]) by mx1.FreeBSD.org (Postfix) with ESMTP id A3E9C43FBF for ; Sat, 2 Aug 2003 13:51:04 -0700 (PDT) (envelope-from dan@dan.emsphone.com) Received: (from dan@localhost) by dan.emsphone.com (8.12.9/8.12.9) id h72Kotmc015846; Sat, 2 Aug 2003 15:50:55 -0500 (CDT) (envelope-from dan) Date: Sat, 2 Aug 2003 15:50:55 -0500 From: Dan Nelson To: "Ryan T. Dean" Message-ID: <20030802205055.GB38843@dan.emsphone.com> References: <3F2BAC6B.3040606@cytherianage.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <3F2BAC6B.3040606@cytherianage.net> X-OS: FreeBSD 5.1-CURRENT X-message-flag: Outlook Error User-Agent: Mutt/1.5.4i cc: freebsd-current@freebsd.org 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 20:51:05 -0000 In the last episode (Aug 02), Ryan T. Dean said: > 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? A memory leak is memory allocated, used, then discarded by the program without freeing, possibly repeatedly so you build up memory that the program never uses and cannot reclaim. These buffers /are/ used, every time you use stdio to stdout or stderr, so it's not a leak. They're simply not freed on exit. > 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 The stdio buffers are correctly flushed by exit(), but fclose() is not called to free the buffers. Why bother when the memory will be deallocated in .0001 seconds when the process exits? :) If you want, you can swap the comment on the two lines in src/lib/libc/stdio/findfp.c to close all open files on exit: void _cleanup() { /* (void) _fwalk(fclose); */ (void) _fwalk(__sflush); /* `cheating' */ } -- Dan Nelson dnelson@allantgroup.com