Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Feb 2000 08:34:50 -0800 (PST)
From:      hostetlb@agcs.com
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   ports/16882: Memory leak with g++ 2.8.1 and STL 2.8.1.1 list / map
Message-ID:  <200002211634.IAA96157@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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 <list>

typedef list<int> IntList;

void producer(IntList &l);
void consumer();

#endif


-- file : consumer.C --

#include "header.H"
#include <unistd.h>
#include <stdio.h>

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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200002211634.IAA96157>