From owner-freebsd-ports Mon Feb 21 8:40: 5 2000 Delivered-To: freebsd-ports@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 8494537B923 for ; Mon, 21 Feb 2000 08:40:01 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id IAA96691; Mon, 21 Feb 2000 08:40:01 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 9422637BE05 for ; Mon, 21 Feb 2000 08:34:50 -0800 (PST) (envelope-from nobody@FreeBSD.org) Received: (from nobody@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id IAA96157; Mon, 21 Feb 2000 08:34:50 -0800 (PST) (envelope-from nobody@FreeBSD.org) Message-Id: <200002211634.IAA96157@freefall.freebsd.org> Date: Mon, 21 Feb 2000 08:34:50 -0800 (PST) From: hostetlb@agcs.com To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-1.0 Subject: ports/16882: Memory leak with g++ 2.8.1 and STL 2.8.1.1 list / map Sender: owner-freebsd-ports@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 16882 >Category: ports >Synopsis: Memory leak with g++ 2.8.1 and STL 2.8.1.1 list / map >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-ports >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Feb 21 08:40:00 PST 2000 >Closed-Date: >Last-Modified: >Originator: Bly Hostetler >Release: 2.2.8 >Organization: AG Communication Systems >Environment: FreeBSD plato-t1.labs.agcs.com 2.2.8-RELEASE FreeBSD 2.2.8-RELEASE #1: Wed Aug 4 22:24:59 GMT 1999 i386 >Description: We have discovered a memory leak problem using FreeBSD 2.2.8, g++ version 2.8.1, and GNU STL libraries (libstdc++) version 2.8.1.1. We are also using the gcc28 patches provided by the FreeBSD web-site. The problem appears when you have two C++ files sharing an STL list, set / multiset or map / multimap. There is actually a larger problem with static variables in template classes, but the STL objects are the easiest way to produce this problem. One of the files inserts entries into the list (causing memory allocation), while the other file releases the entries from the list (returning the memory to an STL allocator). Examining the assembler file created for the two objects, we saw ".weak" definitions for the STL allocator's free_list (among many other weak definitions), which we would expect the linker to combine into a single actual location in the final executable. Even running "nm" on the final executable only shows one free_list variable. However, using gdb to step through the code, and examining where the allocation and deallocation routines were actually accessing the free_list showed that the linker had actually kept each free_list, and all references to each was kept local within each object file. This caused one STL allocator to continually go to the OS to get memory to add to the list, while another STL allocator was releasing those blocks back into its own private buffer. >How-To-Repeat: The following code can be used to produce the problem. 1. Compile it using "g++ -o leak *.C" 2. Start "top" in a separate window. 3. Run "leak", and watch the size of the process grow through each iteration. -- file : header.H -- #ifndef __header_H #define __header_H #include typedef list IntList; void producer(IntList &l); void consumer(); #endif -- file : consumer.C -- #include "header.H" #include #include main() { for (int i = 0; i < 20; i++) { IntList l; producer(l); l.clear(); printf("Done with pass %d\n", i+1); sleep(1); } } -- file : producer.C -- #include "header.H" // Simply adds list_size entries to the list. The caller will release them void producer(IntList &l) { for (int i = 0; i < 100000; i++) { l.push_back(1); } } >Fix: We were able to work around this problem by patching the gcc28 patches. We removed the following patch from "patch-01", which has the effect of disabling gcc's use of weak variable declarations : + +#define ASM_WEAKEN_LABEL(FILE,NAME) \ + do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \ + fputc ('\n', FILE); } while (0) + After applying this patch and recompiling, only one free_list exists in the executable, and the memory leak goes away. >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-ports" in the body of the message