From owner-freebsd-current@FreeBSD.ORG Thu Oct 19 17:29:20 2006 Return-Path: X-Original-To: freebsd-current@freebsd.org 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 4518116A4C9; Thu, 19 Oct 2006 17:29:20 +0000 (UTC) (envelope-from bakul@bitblocks.com) Received: from mail.bitblocks.com (bitblocks.com [209.204.185.216]) by mx1.FreeBSD.org (Postfix) with ESMTP id 496C743D94; Thu, 19 Oct 2006 17:29:05 +0000 (GMT) (envelope-from bakul@bitblocks.com) Received: from bitblocks.com (localhost.bitblocks.com [127.0.0.1]) by mail.bitblocks.com (Postfix) with ESMTP id 523E15B59; Thu, 19 Oct 2006 10:29:03 -0700 (PDT) To: "Sean C. Farley" In-reply-to: Your message of "Thu, 19 Oct 2006 11:54:37 CDT." <20061019112601.J91957@thor.farley.org> Date: Thu, 19 Oct 2006 10:29:03 -0700 From: Bakul Shah Message-Id: <20061019172903.523E15B59@mail.bitblocks.com> Cc: freebsd-current@freebsd.org Subject: Re: Fix for memory leak in setenv/unsetenv X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 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: Thu, 19 Oct 2006 17:29:20 -0000 > I preserve the leak, but I also make use of old entries with matching > names if their size is big enough. The maximum size of the value is > recorded at allocation. The code in the source tree uses the strlen() > of the current value which can shrink even if the space is available. > > Example: > setenv("FOO", "BAR1", 1); > w = getenv("FOO"); > setenv("FOO", "BARBAR1", 1); > x = getenv("FOO"); > setenv("FOO", "BAR2", 1); > y = getenv("FOO"); > setenv("FOO", "BARBAR2", 1); > z = getenv("FOO"); > > This will end up with w == y ("BAR2") and y == z ("BAR1"). w was > allocated first in the array of variables. x is then allocated since w > is too small. y finds w within the array and reuses it. z does the > wame with x. If the larger value had been allocated first, then all > setenv() calls would have used the same storage space. Yes, there is a > leak, but flipping back and forth does not cause the leak to keep > growing. Also, there would be no need to space-pad a value to prevent > the leak. Consider > w = getenv("FOO"); > setenv("FOO", "BARBAR1", 1); > x = getenv("FOO"); The C standard says that the value returned by getenv() shall *not* be modified. AFAIK it doesn't have setenv(). Which leads me to think that in the above example what w points to *must not* change as a result of a subsequent setenv() -- w value must be a constant until the program terminates or another w = getenv(...) is done. Note that setenv() & getenv() may be called in totally separate modules, developed by different people at different times. You are stuck with a leak (IMHO a small price to pay for cleaner & standard complying semantics -- you can always use a conservative GC such as Boehm-Weiser if leak is a major problem and you care enough). I think this is what John Baldwin was referring to by "intentional leak". Please don't "fix" the leak.