bug-ncurses
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: gnu/98975: ncurses: tgetent leaks nearly 10 KB of memory every time


From: Matt
Subject: Re: gnu/98975: ncurses: tgetent leaks nearly 10 KB of memory every time it is called
Date: Sat, 17 Jun 2006 14:58:34 -0700
User-agent: Mutt/1.4.2.1i

FreeBSD bug report: http://www.freebsd.org/cgi/query-pr.cgi?pr=98975

Dear FreeBSD, GNU ncurses, and GNU screen folks,

I wrote earlier that the 10 KB per call memory leak in tgetent seems
to be fixed in ncurses version 5.5. That's still true, however I
have since learned that the leak is only fixed if tgetent is called
with the same terminal name each time. If the terminal name changes,
for example alternating tgetent calls for "vt100" and "sun", it
leaks memory, again about 10 KB per call.

Unfortunately that is exactly how GNU screen uses tgetent. Every
time a user reattaches to their running GNU screen session, it calls
tgetent for $TERM and then calls tgetent again for the "screen"
terminal. This forces my users to restart their long-running screen
sessions periodically, due to all the screen processes each growing
several megabytes per month.

Here's how to reproduce this leak on FreeBSD:

1) Install ncurses 5.5 from /usr/ports/devel/ncurses
2) Compile the following program with it using this command:
     cc tgetentaltloop.c -o tgetentaltloop -static -L/usr/local/lib -ltinfo

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

3) Run tgetentaltloop and observe (using "ps" or "top") that it
   grows in size about 3 MB per second.

This is using ncurses 5.5 as built by FreeBSD ports/devel/ncurses
with their Makefile revision 1.36:
http://www.freebsd.org/cgi/cvsweb.cgi/ports/devel/ncurses/

To help identify the leak, I modified the above program to loop 100
times instead of forever, like so:

#include <termcap.h>
#include <unistd.h>
int
main()
{
    int x;
    for (x = 0; x < 100; x++) {
        tgetent(NULL, "vt100");
        tgetent(NULL, "sun");
        write(1, ".", 1);
        usleep(5000);
    }
} 

and then linked it with the ccmalloc library. Here's the report:

.--------------------------------------------------------------------------.
|================ ccmalloc-0.4.0 (C) 1997-2003 Armin Biere ================|
+--------------------------------------------------------------------------+
| executable       = /home/user/tgetentaltloop                             |
| startup file     = .ccmalloc                                             |
| log file         = /home/user/tgetentdbg/log.95456                       |
| start time       = Sat Jun 17 14:44:40 2006                              |
| operating system = FreeBSD 6.1-RELEASE amd64 on example.com              |
+--------------------------------------------------------------------------+
| only-count        = 0            keep-deallocated-data = 0               |
| check-interval    = 0            check-free-space      = 0               |
| check-start       = 0            file-info             = 1               |
| chain-length      = 0            additional-line       = 1               |
| check-underwrites = 0            print-addresses       = 0               |
| check-overwrites  = 0            print-on-one-line     = 0               |
| sort-by-wasted    = 1            sort-by-size          = 1               |
| # only-log-chain  = 0            continue              = 0               |
| # dont-log-chain  = 0            statistics            = 0               |
| debug             = 0            library-chains        = 0               |
| load-dynlibs      = 1            align-8-byte          = 0               |
| only-wasting-alloc= 1                                                    |
`--------------------------------------------------------------------------'

.---------------.
|ccmalloc report|
=======================================================
| total # of|   allocated | deallocated |     garbage |
+-----------+-------------+-------------+-------------+
|      bytes|      829522 |        9508 |      820014 |
+-----------+-------------+-------------+-------------+
|allocations|        2205 |         702 |        1503 |
+-----------------------------------------------------+
| number of checks: 1                                 |
| number of counts: 2907                              |
| retrieving function names for addresses ... done.   |
| reading file info from gdb ... done.                |
| sorting by number of not reclaimed bytes ... done.  |
| number of call chains: 15                           |
| number of ignored call chains: 0                    |
| number of reported call chains: 15                  |
| number of internal call chains: 15                  |
| number of library call chains: 1                    |
=======================================================
|
* 40.4% = 323.4 KB of garbage allocated in 100 allocations
|       |
|       |       0x00402034 in <main>
|       |                  at tgetentaltloop.c:8
|       |
|       |       0x00402098 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:77
|       |
|       |       0x00404556 in <_nc_setupterm>
|       |                  at ../../ncurses/tinfo/lib_setup.c:484
|       |
|       |       0x00403fd9 in <grab_entry>
|       |                  at ../../ncurses/tinfo/lib_setup.c:276
|       |
|       |       0x004070d8 in <_nc_read_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:514
|       |
|       |       0x00406ef2 in <_nc_read_terminfo_dirs>
|       |                  at ../../ncurses/tinfo/read_entry.c:444
|       |
|       |       0x00406e51 in <_nc_read_tic_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:419
|       |
|       |       0x00406dbc in <_nc_read_file_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:397
|       |
|       |       0x004066af in <read_termtype>
|       |                  at ../../ncurses/tinfo/read_entry.c:239
|       |
|       |       0x004124e6 in <calloc>
|       |
|       `-----> 0x004123fe in <malloc>
|        
* 40.4% = 323.4 KB of garbage allocated in 100 allocations
|       |
|       |       0x00402043 in <main>
|       |                  at tgetentaltloop.c:9
|       |
|       |       0x00402098 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:77
|       |
|       |       0x00404556 in <_nc_setupterm>
|       |                  at ../../ncurses/tinfo/lib_setup.c:484
|       |
|       |       0x00403fd9 in <grab_entry>
|       |                  at ../../ncurses/tinfo/lib_setup.c:276
|       |
|       |       0x004070d8 in <_nc_read_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:514
|       |
|       |       0x00406ef2 in <_nc_read_terminfo_dirs>
|       |                  at ../../ncurses/tinfo/read_entry.c:444
|       |
|       |       0x00406e51 in <_nc_read_tic_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:419
|       |
|       |       0x00406dbc in <_nc_read_file_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:397
|       |
|       |       0x004066af in <read_termtype>
|       |                  at ../../ncurses/tinfo/read_entry.c:239
|       |
|       |       0x004124e6 in <calloc>
|       |
|       `-----> 0x004123fe in <malloc>
|        
|  6.7% = 53.3 KB of garbage allocated in 100 allocations
|       |
|       |       0x00402034 in <main>
|       |                  at tgetentaltloop.c:8
|       |
|       |       0x00402098 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:77
|       |
|       |       0x00404556 in <_nc_setupterm>
|       |                  at ../../ncurses/tinfo/lib_setup.c:484
|       |
|       |       0x00403fd9 in <grab_entry>
|       |                  at ../../ncurses/tinfo/lib_setup.c:276
|       |
|       |       0x004070d8 in <_nc_read_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:514
|       |
|       |       0x00406ef2 in <_nc_read_terminfo_dirs>
|       |                  at ../../ncurses/tinfo/read_entry.c:444
|       |
|       |       0x00406e51 in <_nc_read_tic_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:419
|       |
|       |       0x00406dbc in <_nc_read_file_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:397
|       |
|       |       0x0040640c in <read_termtype>
|       |                  at ../../ncurses/tinfo/read_entry.c:196
|       |
|       `-----> 0x004123fe in <malloc>
|        
|  3.8% = 30.6 KB of garbage allocated in 100 allocations
|       |
|       |       0x00402043 in <main>
|       |                  at tgetentaltloop.c:9
|       |
|       |       0x00402098 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:77
|       |
|       |       0x00404556 in <_nc_setupterm>
|       |                  at ../../ncurses/tinfo/lib_setup.c:484
|       |
|       |       0x00403fd9 in <grab_entry>
|       |                  at ../../ncurses/tinfo/lib_setup.c:276
|       |
|       |       0x004070d8 in <_nc_read_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:514
|       |
|       |       0x00406ef2 in <_nc_read_terminfo_dirs>
|       |                  at ../../ncurses/tinfo/read_entry.c:444
|       |
|       |       0x00406e51 in <_nc_read_tic_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:419
|       |
|       |       0x00406dbc in <_nc_read_file_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:397
|       |
|       |       0x0040640c in <read_termtype>
|       |                  at ../../ncurses/tinfo/read_entry.c:196
|       |
|       `-----> 0x004123fe in <malloc>
|        
|  2.1% = 17.2 KB of garbage allocated in 100 allocations
|       |
|       |       0x00402034 in <main>
|       |                  at tgetentaltloop.c:8
|       |
|       |       0x00402098 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:77
|       |
|       |       0x00404501 in <_nc_setupterm>
|       |                  at ../../ncurses/tinfo/lib_setup.c:477
|       |
|       |       0x004124e6 in <calloc>
|       |
|       `-----> 0x004123fe in <malloc>
|        
|  2.1% = 17.2 KB of garbage allocated in 100 allocations
|       |
|       |       0x00402043 in <main>
|       |                  at tgetentaltloop.c:9
|       |
|       |       0x00402098 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:77
|       |
|       |       0x00404501 in <_nc_setupterm>
|       |                  at ../../ncurses/tinfo/lib_setup.c:477
|       |
|       |       0x004124e6 in <calloc>
|       |
|       `-----> 0x004123fe in <malloc>
|        
|  0.10% = 7800 Bytes of garbage allocated in 100 allocations
|       |
|       |       0x00402034 in <main>
|       |                  at tgetentaltloop.c:8
|       |
|       |       0x00402098 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:77
|       |
|       |       0x00404556 in <_nc_setupterm>
|       |                  at ../../ncurses/tinfo/lib_setup.c:484
|       |
|       |       0x00403fd9 in <grab_entry>
|       |                  at ../../ncurses/tinfo/lib_setup.c:276
|       |
|       |       0x004070d8 in <_nc_read_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:514
|       |
|       |       0x00406ef2 in <_nc_read_terminfo_dirs>
|       |                  at ../../ncurses/tinfo/read_entry.c:444
|       |
|       |       0x00406e51 in <_nc_read_tic_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:419
|       |
|       |       0x00406dbc in <_nc_read_file_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:397
|       |
|       |       0x0040660d in <read_termtype>
|       |                  at ../../ncurses/tinfo/read_entry.c:233
|       |
|       |       0x004124e6 in <calloc>
|       |
|       `-----> 0x004123fe in <malloc>
|        
|  0.10% = 7800 Bytes of garbage allocated in 100 allocations
|       |
|       |       0x00402043 in <main>
|       |                  at tgetentaltloop.c:9
|       |
|       |       0x00402098 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:77
|       |
|       |       0x00404556 in <_nc_setupterm>
|       |                  at ../../ncurses/tinfo/lib_setup.c:484
|       |
|       |       0x00403fd9 in <grab_entry>
|       |                  at ../../ncurses/tinfo/lib_setup.c:276
|       |
|       |       0x004070d8 in <_nc_read_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:514
|       |
|       |       0x00406ef2 in <_nc_read_terminfo_dirs>
|       |                  at ../../ncurses/tinfo/read_entry.c:444
|       |
|       |       0x00406e51 in <_nc_read_tic_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:419
|       |
|       |       0x00406dbc in <_nc_read_file_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:397
|       |
|       |       0x0040660d in <read_termtype>
|       |                  at ../../ncurses/tinfo/read_entry.c:233
|       |
|       |       0x004124e6 in <calloc>
|       |
|       `-----> 0x004123fe in <malloc>
|        
|  0.7% = 5600 Bytes of garbage allocated in 100 allocations
|       |
|       |       0x00402043 in <main>
|       |                  at tgetentaltloop.c:9
|       |
|       |       0x00402098 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:77
|       |
|       |       0x00404556 in <_nc_setupterm>
|       |                  at ../../ncurses/tinfo/lib_setup.c:484
|       |
|       |       0x00403fd9 in <grab_entry>
|       |                  at ../../ncurses/tinfo/lib_setup.c:276
|       |
|       |       0x004070d8 in <_nc_read_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:514
|       |
|       |       0x00406ef2 in <_nc_read_terminfo_dirs>
|       |                  at ../../ncurses/tinfo/read_entry.c:444
|       |
|       |       0x00406e51 in <_nc_read_tic_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:419
|       |
|       |       0x00406dbc in <_nc_read_file_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:397
|       |
|       |       0x004064dd in <read_termtype>
|       |                  at ../../ncurses/tinfo/read_entry.c:210
|       |
|       |       0x004124e6 in <calloc>
|       |
|       `-----> 0x004123fe in <malloc>
|        
|  0.5% = 4400 Bytes of garbage allocated in 100 allocations
|       |
|       |       0x00402034 in <main>
|       |                  at tgetentaltloop.c:8
|       |
|       |       0x00402098 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:77
|       |
|       |       0x00404556 in <_nc_setupterm>
|       |                  at ../../ncurses/tinfo/lib_setup.c:484
|       |
|       |       0x00403fd9 in <grab_entry>
|       |                  at ../../ncurses/tinfo/lib_setup.c:276
|       |
|       |       0x004070d8 in <_nc_read_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:514
|       |
|       |       0x00406ef2 in <_nc_read_terminfo_dirs>
|       |                  at ../../ncurses/tinfo/read_entry.c:444
|       |
|       |       0x00406e51 in <_nc_read_tic_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:419
|       |
|       |       0x00406dbc in <_nc_read_file_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:397
|       |
|       |       0x004064dd in <read_termtype>
|       |                  at ../../ncurses/tinfo/read_entry.c:210
|       |
|       |       0x004124e6 in <calloc>
|       |
|       `-----> 0x004123fe in <malloc>
|        
|  0.5% = 4400 Bytes of garbage allocated in 100 allocations
|       |
|       |       0x00402034 in <main>
|       |                  at tgetentaltloop.c:8
|       |
|       |       0x00402098 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:77
|       |
|       |       0x00404556 in <_nc_setupterm>
|       |                  at ../../ncurses/tinfo/lib_setup.c:484
|       |
|       |       0x00403fd9 in <grab_entry>
|       |                  at ../../ncurses/tinfo/lib_setup.c:276
|       |
|       |       0x004070d8 in <_nc_read_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:514
|       |
|       |       0x00406ef2 in <_nc_read_terminfo_dirs>
|       |                  at ../../ncurses/tinfo/read_entry.c:444
|       |
|       |       0x00406e51 in <_nc_read_tic_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:419
|       |
|       |       0x00406dbc in <_nc_read_file_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:397
|       |
|       |       0x00406569 in <read_termtype>
|       |                  at ../../ncurses/tinfo/read_entry.c:219
|       |
|       |       0x004124e6 in <calloc>
|       |
|       `-----> 0x004123fe in <malloc>
|        
|  0.5% = 4400 Bytes of garbage allocated in 100 allocations
|       |
|       |       0x00402043 in <main>
|       |                  at tgetentaltloop.c:9
|       |
|       |       0x00402098 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:77
|       |
|       |       0x00404556 in <_nc_setupterm>
|       |                  at ../../ncurses/tinfo/lib_setup.c:484
|       |
|       |       0x00403fd9 in <grab_entry>
|       |                  at ../../ncurses/tinfo/lib_setup.c:276
|       |
|       |       0x004070d8 in <_nc_read_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:514
|       |
|       |       0x00406ef2 in <_nc_read_terminfo_dirs>
|       |                  at ../../ncurses/tinfo/read_entry.c:444
|       |
|       |       0x00406e51 in <_nc_read_tic_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:419
|       |
|       |       0x00406dbc in <_nc_read_file_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:397
|       |
|       |       0x00406569 in <read_termtype>
|       |                  at ../../ncurses/tinfo/read_entry.c:219
|       |
|       |       0x004124e6 in <calloc>
|       |
|       `-----> 0x004123fe in <malloc>
|        
|  0.0% = 77 Bytes of garbage allocated in 1 allocation
|       |
|       |       0x00402034 in <main>
|       |                  at tgetentaltloop.c:8
|       |
|       |       0x004021f6 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:99
|       |
|       |       0x004036d3 in <_nc_trim_sgr0>
|       |                  at ../../ncurses/tinfo/trim_sgr0.c:236
|       |
|       |       0x00403114 in <set_attribute_9>
|       |                  at ../../ncurses/tinfo/trim_sgr0.c:54
|       |
|       |       0x00404e17 in <tparm>
|       |                  at ../../ncurses/tinfo/lib_tparm.c:788
|       |
|       |       0x00404e9e in <tparam_internal>
|       |                  at ../../ncurses/tinfo/lib_tparm.c:502
|       |
|       |       0x00404880 in <_nc_tparm_analyze>
|       |                  at ../../ncurses/tinfo/lib_tparm.c:374
|       |
|       |       0x0040788e in <_nc_doalloc>
|       |                  at ../../ncurses/tinfo/doalloc.c:55
|       |
|       `-----> 0x004123fe in <malloc>
|        
|  0.0% = 23 Bytes of garbage allocated in 1 allocation
|       |
|       |       0x00402034 in <main>
|       |                  at tgetentaltloop.c:8
|       |
|       |       0x00402098 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:77
|       |
|       |       0x00404556 in <_nc_setupterm>
|       |                  at ../../ncurses/tinfo/lib_setup.c:484
|       |
|       |       0x00403fd9 in <grab_entry>
|       |                  at ../../ncurses/tinfo/lib_setup.c:276
|       |
|       |       0x00407056 in <_nc_read_entry>
|       |                  at ../../ncurses/tinfo/read_entry.c:498
|       |
|       |       0x00407ad3 in <_nc_home_terminfo>
|       |                  at ../../ncurses/tinfo/home_terminfo.c:58
|       |
|       `-----> 0x004123fe in <malloc>
|        
|  0.0% = 14 Bytes of garbage allocated in 1 allocation
|       |
|       |       0x00402034 in <main>
|       |                  at tgetentaltloop.c:8
|       |
|       |       0x004021f6 in <tgetent>
|       |                  at ../../ncurses/tinfo/lib_termcap.c:99
|       |
|       |       0x004036d3 in <_nc_trim_sgr0>
|       |                  at ../../ncurses/tinfo/trim_sgr0.c:236
|       |
|       |       0x00403114 in <set_attribute_9>
|       |                  at ../../ncurses/tinfo/trim_sgr0.c:54
|       |
|       |       0x00404e17 in <tparm>
|       |                  at ../../ncurses/tinfo/lib_tparm.c:788
|       |
|       |       0x00405099 in <tparam_internal>
|       |                  at ../../ncurses/tinfo/lib_tparm.c:549
|       |
|       |       0x00405ae2 in <save_char>
|       |                  at ../../ncurses/tinfo/lib_tparm.c:191
|       |
|       |       0x00405888 in <get_space>
|       |                  at ../../ncurses/tinfo/lib_tparm.c:155
|       |
|       |       0x00407864 in <_nc_doalloc>
|       |                  at ../../ncurses/tinfo/doalloc.c:50
|       |
|       |       0x0041267a in <realloc>
|       |
|       |       0x0041252d in <_realloc>
|       |
|       `-----> 0x004123fe in <malloc>
|        
`------------------------------------------------------




reply via email to

[Prev in Thread] Current Thread [Next in Thread]