Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Jun 2006 08:55:06 GMT
From:      Matt <freebsdbugs@fjarlq.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   gnu/98975: ncurses: tgetent leaks nearly 10 KB of memory every time it is called
Message-ID:  <200606150855.k5F8t6WO009611@www.freebsd.org>
Resent-Message-ID: <200606150900.k5F90ZiJ090650@freefall.freebsd.org>

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

>Number:         98975
>Category:       gnu
>Synopsis:       ncurses: tgetent leaks nearly 10 KB of memory every time it is called
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jun 15 09:00:35 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Matt
>Release:        6.1-RELEASE
>Organization:
>Environment:
Observed on both amd64 and i386. Here's my cc -v for the demo program below:

% cc -v tgetentloop.c -o tgetentloop -ltinfo
Using built-in specs.
Configured with: FreeBSD/amd64 system compiler
Thread model: posix
gcc version 3.4.4 [FreeBSD] 20050518
 /usr/libexec/cc1 -quiet -v -D_LONGLONG tgetentloop.c -quiet -dumpbase tgetentloop.c -auxbase tgetentloop -version -o /var/tmp//ccdB95Tg.s
ignoring duplicate directory "/usr/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include
End of search list.
GNU C version 3.4.4 [FreeBSD] 20050518 (amd64-undermydesk-freebsd)
        compiled by GNU C version 3.4.4 [FreeBSD] 20050518.
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
 /usr/bin/as -V -Qy -o /var/tmp//ccQbQvZT.o /var/tmp//ccdB95Tg.s
GNU assembler version 2.15 [FreeBSD] 2004-05-23 (x86_64-obrien-freebsd) using BFD version 2.15 [FreeBSD] 2004-05-23
 /usr/bin/ld -V -dynamic-linker /libexec/ld-elf.so.1 -o tgetentloop /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib /var/tmp//ccQbQvZT.o -ltinfo -lgcc -lc -lgcc /usr/lib/crtend.o /usr/lib/crtn.o
GNU ld version 2.15 [FreeBSD] 2004-05-23
  Supported emulations:
   elf_i386_fbsd
   elf_x86_64_fbsd
>Description:
This program demonstrates a large memory leak in tgetent:

#include <termcap.h>
#include <unistd.h>
int
main()
{
    while (1) {
        tgetent(NULL, "vt100");
        write(1, ".", 1);
        usleep(5000);
    }
}

Compile with this command:
  cc tgetentloop.c -o tgetentloop -ltinfo

Run it and watch the memory size grow with "top". This leaks about 3 MB/sec on my amd64 system. 1,000 calls to tgetent consistently leak 9,660 KB, so about 10 KB/call.
>How-To-Repeat:
No, I don't need to call tgetent 200 times per second :), but this leak is actually affecting me in a significant way. I have a FreeBSD server where many users run long-running programs from within GNU screen version 4.0.2. Every time they attach to their GNU screen session, tgetent() gets called (several times per reattach, I believe).

I've been keeping daily process memory usage stats for a couple years on this server. The last time I restarted my screen (which is painful, requiring me to restart all the programs inside it) was December 6, 2005; on that day my screen was using 6,088 KB. On June 15, 2006 that same screen process was using 83,456 KB. This was one of the major memory leaks that caused my system to run out of swap space a few months ago. Periodically my users have to restart their screen sessions to relinquish the leaked memory.

I studied the problem for a few hours using ccmalloc to catch memory leaks in screen, and I don't think this is the only memory leak in GNU screen, but it is by far the most serious. 
>Fix:
The bug exists in the ncurses version 5.2-20020615 code that ships with FreeBSD 6.1-RELEASE. The leak seems to be almost entirely fixed in ncurses 5.5:

1) Install ncurses 5.5 from /usr/ports/devel/ncurses
2) Link above program with it using this command:
     cc tgetentloop.c -o tgetentloop -static -L/usr/local/lib -ltinfo
3) Run tgetentloop and observe that it only grows 4 KB/sec on amd64 instead of 3 MB/sec as with the stock FreeBSD libtinfo.

So there's still a really tiny leak somewhere in there, sigh.
>Release-Note:
>Audit-Trail:
>Unformatted:



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