Debian Bug report logs - #493465
libncurses5: allocates memory that is never freed

version graph

Package: libncurses5; Maintainer for libncurses5 is Craig Small <csmall@debian.org>; Source for libncurses5 is src:ncurses.

Reported by: "brian m. carlson" <sandals@crustytoothpaste.net>

Date: Sat, 2 Aug 2008 19:33:04 UTC

Severity: normal

Found in version ncurses/5.6+20080713-1

Reply or subscribe to this bug.

Toggle useless messages

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to debian-bugs-dist@lists.debian.org, Daniel Baumann <daniel@debian.org>:
Bug#493465; Package libncurses5. Full text and rfc822 format available.

Acknowledgement sent to "brian m. carlson" <sandals@crustytoothpaste.ath.cx>:
New Bug report received and forwarded. Copy sent to Daniel Baumann <daniel@debian.org>. Full text and rfc822 format available.

Message #5 received at submit@bugs.debian.org (full text, mbox):

From: "brian m. carlson" <sandals@crustytoothpaste.ath.cx>
To: Debian Bug Tracking System <submit@bugs.debian.org>
Subject: libncurses5: allocates memory that is never freed
Date: Sat, 2 Aug 2008 19:29:22 +0000
[Message part 1 (text/plain, inline)]
Package: libncurses5
Version: 5.6+20080713-1
Severity: normal

According to valgrind, libncurses5 allocates approximately 118k that is
never freed:

==31792== 8 bytes in 1 blocks are still reachable in loss record 1 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x505F410: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 15 bytes in 1 blocks are still reachable in loss record 2 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x5CCADB1: strdup (strdup.c:43)
==31792==    by 0x506C2A6: _nc_setupterm (in /lib/libncurses.so.5.6)
==31792==    by 0x505CAF7: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 18 bytes in 1 blocks are still reachable in loss record 3 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x506D5EF: _nc_tparm_analyze (in /lib/libncurses.so.5.6)
==31792==    by 0x506D859: tparm (in /lib/libncurses.so.5.6)
==31792==    by 0x505B62C: _nc_mvcur_init (in /lib/libncurses.so.5.6)
==31792==    by 0x505CC61: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 22 bytes in 1 blocks are still reachable in loss record 4 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x506A4BC: _nc_home_terminfo (in /lib/libncurses.so.5.6)
==31792==    by 0x506A124: _nc_next_db (in /lib/libncurses.so.5.6)
==31792==    by 0x507053B: _nc_read_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x506BDB5: (within /lib/libncurses.so.5.6)
==31792==    by 0x506C26F: _nc_setupterm (in /lib/libncurses.so.5.6)
==31792==    by 0x505CAF7: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 24 bytes in 1 blocks are still reachable in loss record 5 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x50688A4: _nc_add_to_try (in /lib/libncurses.so.5.6)
==31792==    by 0x506A556: _nc_init_keytry (in /lib/libncurses.so.5.6)
==31792==    by 0x506B20B: _nc_keypad (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD80: TextRenderer::TextRenderer() (textrenderer.cc:12)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 128 bytes in 1 blocks are still reachable in loss record 6 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x505F3DD: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 168 bytes in 1 blocks are still reachable in loss record 7 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x5053673: _nc_scroll_optimize (in /lib/libncurses.so.5.6)
==31792==    by 0x5067364: doupdate (in /lib/libncurses.so.5.6)
==31792==    by 0x505E52C: wrefresh (in /lib/libncurses.so.5.6)
==31792==    by 0x41CB5A: TextRenderer::DisplayTitleScreen() (textrenderer.cc:25)
==31792==    by 0x41F81F: Renderer::DoMessage(Renderer::Message&) (renderer.cc:25)
==31792==    by 0x41FC67: Renderer::DoMainLoop() (renderer.cc:61)
==31792==    by 0x415273: Game::DoRenderer(void*) (game.cc:132)
==31792==    by 0x4E2BFC6: start_thread (pthread_create.c:297)
==31792==    by 0x5D1F7CC: clone (in /usr/lib/debug/libc-2.7.so)
==31792== 
==31792== 
==31792== 208 bytes in 1 blocks are still reachable in loss record 8 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x506C255: _nc_setupterm (in /lib/libncurses.so.5.6)
==31792==    by 0x505CAF7: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 224 bytes in 2 blocks are still reachable in loss record 9 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x505CF15: _nc_makenew (in /lib/libncurses.so.5.6)
==31792==    by 0x505D484: newwin (in /lib/libncurses.so.5.6)
==31792==    by 0x505F81B: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 336 bytes in 1 blocks are still reachable in loss record 10 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x50547FF: _nc_hash_map (in /lib/libncurses.so.5.6)
==31792==    by 0x5053699: _nc_scroll_optimize (in /lib/libncurses.so.5.6)
==31792==    by 0x5067364: doupdate (in /lib/libncurses.so.5.6)
==31792==    by 0x505E52C: wrefresh (in /lib/libncurses.so.5.6)
==31792==    by 0x41CB5A: TextRenderer::DisplayTitleScreen() (textrenderer.cc:25)
==31792==    by 0x41F81F: Renderer::DoMessage(Renderer::Message&) (renderer.cc:25)
==31792==    by 0x41FC67: Renderer::DoMainLoop() (renderer.cc:61)
==31792==    by 0x415273: Game::DoRenderer(void*) (game.cc:132)
==31792==    by 0x4E2BFC6: start_thread (pthread_create.c:297)
==31792==    by 0x5D1F7CC: clone (in /usr/lib/debug/libc-2.7.so)
==31792== 
==31792== 
==31792== 336 bytes in 1 blocks are still reachable in loss record 11 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x50546E0: _nc_hash_map (in /lib/libncurses.so.5.6)
==31792==    by 0x5053699: _nc_scroll_optimize (in /lib/libncurses.so.5.6)
==31792==    by 0x5067364: doupdate (in /lib/libncurses.so.5.6)
==31792==    by 0x505E52C: wrefresh (in /lib/libncurses.so.5.6)
==31792==    by 0x41CB5A: TextRenderer::DisplayTitleScreen() (textrenderer.cc:25)
==31792==    by 0x41F81F: Renderer::DoMessage(Renderer::Message&) (renderer.cc:25)
==31792==    by 0x41FC67: Renderer::DoMainLoop() (renderer.cc:61)
==31792==    by 0x415273: Game::DoRenderer(void*) (game.cc:132)
==31792==    by 0x4E2BFC6: start_thread (pthread_create.c:297)
==31792==    by 0x5D1F7CC: clone (in /usr/lib/debug/libc-2.7.so)
==31792== 
==31792== 
==31792== 488 bytes in 1 blocks are still reachable in loss record 12 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x507020F: _nc_read_termtype (in /lib/libncurses.so.5.6)
==31792==    by 0x5070412: _nc_read_file_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x50705A0: _nc_read_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x506BDB5: (within /lib/libncurses.so.5.6)
==31792==    by 0x506C26F: _nc_setupterm (in /lib/libncurses.so.5.6)
==31792==    by 0x505CAF7: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 685 bytes in 1 blocks are still reachable in loss record 13 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x507037A: _nc_read_termtype (in /lib/libncurses.so.5.6)
==31792==    by 0x5070412: _nc_read_file_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x50705A0: _nc_read_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x506BDB5: (within /lib/libncurses.so.5.6)
==31792==    by 0x506C26F: _nc_setupterm (in /lib/libncurses.so.5.6)
==31792==    by 0x505CAF7: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 1,024 bytes in 1 blocks are still reachable in loss record 14 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x505F3BE: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 1,314 bytes in 1 blocks are still reachable in loss record 15 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x506FC91: _nc_read_termtype (in /lib/libncurses.so.5.6)
==31792==    by 0x5070412: _nc_read_file_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x50705A0: _nc_read_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x506BDB5: (within /lib/libncurses.so.5.6)
==31792==    by 0x506C26F: _nc_setupterm (in /lib/libncurses.so.5.6)
==31792==    by 0x505CAF7: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 1,344 bytes in 2 blocks are still reachable in loss record 16 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x505CF2E: _nc_makenew (in /lib/libncurses.so.5.6)
==31792==    by 0x505D484: newwin (in /lib/libncurses.so.5.6)
==31792==    by 0x505F81B: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 1,464 bytes in 1 blocks are still reachable in loss record 17 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x505F370: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 2,064 bytes in 1 blocks are still reachable in loss record 18 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x5054357: _nc_hash_map (in /lib/libncurses.so.5.6)
==31792==    by 0x5053699: _nc_scroll_optimize (in /lib/libncurses.so.5.6)
==31792==    by 0x5067364: doupdate (in /lib/libncurses.so.5.6)
==31792==    by 0x505E52C: wrefresh (in /lib/libncurses.so.5.6)
==31792==    by 0x41CB5A: TextRenderer::DisplayTitleScreen() (textrenderer.cc:25)
==31792==    by 0x41F81F: Renderer::DoMessage(Renderer::Message&) (renderer.cc:25)
==31792==    by 0x41FC67: Renderer::DoMainLoop() (renderer.cc:61)
==31792==    by 0x415273: Game::DoRenderer(void*) (game.cc:132)
==31792==    by 0x4E2BFC6: start_thread (pthread_create.c:297)
==31792==    by 0x5D1F7CC: clone (in /usr/lib/debug/libc-2.7.so)
==31792== 
==31792== 
==31792== 2,328 bytes in 97 blocks are still reachable in loss record 19 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x50687EE: _nc_add_to_try (in /lib/libncurses.so.5.6)
==31792==    by 0x506A556: _nc_init_keytry (in /lib/libncurses.so.5.6)
==31792==    by 0x506B20B: _nc_keypad (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD80: TextRenderer::TextRenderer() (textrenderer.cc:12)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 2,800 bytes in 1 blocks are still reachable in loss record 20 of 23
==31792==    at 0x4C20FEB: malloc (vg_replace_malloc.c:207)
==31792==    by 0x5070677: _nc_set_buffer (in /lib/libncurses.so.5.6)
==31792==    by 0x505F4DF: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 3,312 bytes in 138 blocks are still reachable in loss record 21 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x5068864: _nc_add_to_try (in /lib/libncurses.so.5.6)
==31792==    by 0x506A556: _nc_init_keytry (in /lib/libncurses.so.5.6)
==31792==    by 0x506B20B: _nc_keypad (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD80: TextRenderer::TextRenderer() (textrenderer.cc:12)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== 
==31792== 3,974 bytes in 4 blocks are still reachable in loss record 22 of 23
==31792==    at 0x4C210C2: realloc (vg_replace_malloc.c:429)
==31792==    by 0x506A1FA: _nc_doalloc (in /lib/libncurses.so.5.6)
==31792==    by 0x5070136: _nc_read_termtype (in /lib/libncurses.so.5.6)
==31792==    by 0x5070412: _nc_read_file_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x50705A0: _nc_read_entry (in /lib/libncurses.so.5.6)
==31792==    by 0x506BDB5: (within /lib/libncurses.so.5.6)
==31792==    by 0x506C26F: _nc_setupterm (in /lib/libncurses.so.5.6)
==31792==    by 0x505CAF7: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792== 
==31792== 
==31792== 96,096 bytes in 84 blocks are still reachable in loss record 23 of 23
==31792==    at 0x4C200FC: calloc (vg_replace_malloc.c:397)
==31792==    by 0x505D4CC: newwin (in /lib/libncurses.so.5.6)
==31792==    by 0x505F81B: _nc_setupscreen (in /lib/libncurses.so.5.6)
==31792==    by 0x505CB52: newterm (in /lib/libncurses.so.5.6)
==31792==    by 0x5059CA8: initscr (in /lib/libncurses.so.5.6)
==31792==    by 0x41CD4F: TextRenderer::TextRenderer() (textrenderer.cc:7)
==31792==    by 0x415A7E: Game::InitializeThreads() (game.cc:61)
==31792==    by 0x415D35: Game::Run() (game.cc:86)
==31792==    by 0x4176A2: main (main.cc:5)
==31792== 
==31792== LEAK SUMMARY:
==31792==    definitely lost: 0 bytes in 0 blocks.
==31792==      possibly lost: 0 bytes in 0 blocks.
==31792==    still reachable: 118,380 bytes in 344 blocks.
==31792==         suppressed: 0 bytes in 0 blocks.

Calling delwin(stdscr) should free the memory, but it does not.  This is
a problem because every time I want to check if my program is leaking, I
have to go through pages and pages of libncurses5-allocated memory.
Also, minimal memory usage is a requirement for this program, and
ncurses currently provides no way to free this memory, AFAICT.  If there
is such a way, it does not appear to be documented.

-- System Information:
Debian Release: lenny/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.26-1-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to en_US.UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages libncurses5 depends on:
ii  libc6                         2.7-13     GNU C Library: Shared libraries

Versions of packages libncurses5 recommends:
ii  libgpm2                       1.20.4-2   General Purpose Mouse - shared lib

libncurses5 suggests no packages.

-- no debconf information

-- 
brian m. carlson / brian with sandals: Houston, Texas, US
+1 713 440 7475 | http://crustytoothpaste.ath.cx/~bmc | My opinion only
troff on top of XML: http://crustytoothpaste.ath.cx/~bmc/code/thwack
OpenPGP: RSA v4 4096b 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187
[signature.asc (application/pgp-signature, inline)]

Information forwarded to debian-bugs-dist@lists.debian.org, Daniel Baumann <daniel@debian.org>:
Bug#493465; Package libncurses5. Full text and rfc822 format available.

Acknowledgement sent to Thomas Dickey <dickey@his.com>:
Extra info received and forwarded to list. Copy sent to Daniel Baumann <daniel@debian.org>. Full text and rfc822 format available.

Message #10 received at 493465@bugs.debian.org (full text, mbox):

From: Thomas Dickey <dickey@his.com>
To: "brian m. carlson" <sandals@crustytoothpaste.ath.cx>, 493465@bugs.debian.org
Subject: Re: Bug#493465: libncurses5: allocates memory that is never freed
Date: Sat, 2 Aug 2008 19:44:30 -0400 (EDT)
On Sat, 2 Aug 2008, brian m. carlson wrote:

> Package: libncurses5
> Version: 5.6+20080713-1
> Severity: normal
>
> According to valgrind, libncurses5 allocates approximately 118k that is
> never freed:

read the INSTALLATION file in sources, which describes the --disable-leaks 
option

-- 
Thomas E. Dickey
http://invisible-island.net
ftp://invisible-island.net




Information forwarded to debian-bugs-dist@lists.debian.org, Daniel Baumann <daniel@debian.org>:
Bug#493465; Package libncurses5. Full text and rfc822 format available.

Acknowledgement sent to Thomas Dickey <dickey@his.com>:
Extra info received and forwarded to list. Copy sent to Daniel Baumann <daniel@debian.org>. Full text and rfc822 format available.

Message #15 received at 493465@bugs.debian.org (full text, mbox):

From: Thomas Dickey <dickey@his.com>
To: "brian m. carlson" <sandals@crustytoothpaste.ath.cx>, 493465@bugs.debian.org
Subject: Re: Bug#493465: libncurses5: allocates memory that is never freed
Date: Sat, 2 Aug 2008 19:46:49 -0400 (EDT)
On Sat, 2 Aug 2008, brian m. carlson wrote:

> Package: libncurses5
> Version: 5.6+20080713-1
> Severity: normal
>
> According to valgrind, libncurses5 allocates approximately 118k that is
> never freed:

from INSTALL:

    --disable-leaks
        For testing, compile-in code that frees memory that normally would not
        be freed, to simplify analysis of memory-leaks.

        Any implementation of curses must not free the memory associated with
        a screen, since (even after calling endwin()), it must be available
        for use in the next call to refresh().  There are also chunks of
        memory held for performance reasons.  That makes it hard to analyze
        curses applications for memory leaks.  To work around this, build
        a debugging version of the ncurses library which frees those chunks
        which it can, and provides the _nc_free_and_exit() function to free
        the remainder on exit.  The ncurses utility and test programs use this
        feature, e.g., via the ExitProgram() macro.



-- 
Thomas E. Dickey
http://invisible-island.net
ftp://invisible-island.net




Information forwarded to debian-bugs-dist@lists.debian.org, Daniel Baumann <daniel@debian.org>:
Bug#493465; Package libncurses5. Full text and rfc822 format available.

Acknowledgement sent to "brian m. carlson" <sandals@crustytoothpaste.ath.cx>:
Extra info received and forwarded to list. Copy sent to Daniel Baumann <daniel@debian.org>. Full text and rfc822 format available.

Message #20 received at 493465@bugs.debian.org (full text, mbox):

From: "brian m. carlson" <sandals@crustytoothpaste.ath.cx>
To: Thomas Dickey <dickey@his.com>
Cc: 493465@bugs.debian.org
Subject: Re: Bug#493465: libncurses5: allocates memory that is never freed
Date: Sun, 3 Aug 2008 01:00:02 +0000
[Message part 1 (text/plain, inline)]
On Sat, Aug 02, 2008 at 07:46:49PM -0400, Thomas Dickey wrote:
> On Sat, 2 Aug 2008, brian m. carlson wrote:
>
>> Package: libncurses5
>> Version: 5.6+20080713-1
>> Severity: normal
>>
>> According to valgrind, libncurses5 allocates approximately 118k that is
>> never freed:
>
> from INSTALL:
>
>     --disable-leaks
>         For testing, compile-in code that frees memory that normally would not
>         be freed, to simplify analysis of memory-leaks.
>
>         Any implementation of curses must not free the memory associated with
>         a screen, since (even after calling endwin()), it must be available
>         for use in the next call to refresh().  There are also chunks of
>         memory held for performance reasons.  That makes it hard to analyze
>         curses applications for memory leaks.  To work around this, build
>         a debugging version of the ncurses library which frees those chunks
>         which it can, and provides the _nc_free_and_exit() function to free
>         the remainder on exit.  The ncurses utility and test programs use this
>         feature, e.g., via the ExitProgram() macro.

This isn't really a solution unless the libncurses5 package is built
with it.  It's great that you considered this problem and built in an
option to fix it, but it's not compiled into the Debian package, and so
the Debian package leaks memory.  Shared libraries aren't supposed to do
that.

I personally don't believe refresh is required to work after a
delwin(stdscr), since

  Calling delwin deletes the named window, freeing all memory associated
  with it....

except that it doesn't free all the memory associated with it.  It does
free *some* of it, but not all.  I don't see any possible objection to
freeing all the related memory in this case, since calling refresh would
invoke undefined behavior.

-- 
brian m. carlson / brian with sandals: Houston, Texas, US
+1 713 440 7475 | http://crustytoothpaste.ath.cx/~bmc | My opinion only
troff on top of XML: http://crustytoothpaste.ath.cx/~bmc/code/thwack
OpenPGP: RSA v4 4096b 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187
[signature.asc (application/pgp-signature, inline)]

Information forwarded to debian-bugs-dist@lists.debian.org, Daniel Baumann <daniel@debian.org>:
Bug#493465; Package libncurses5. Full text and rfc822 format available.

Acknowledgement sent to Thomas Dickey <dickey@his.com>:
Extra info received and forwarded to list. Copy sent to Daniel Baumann <daniel@debian.org>. Full text and rfc822 format available.

Message #25 received at 493465@bugs.debian.org (full text, mbox):

From: Thomas Dickey <dickey@his.com>
To: "brian m. carlson" <sandals@crustytoothpaste.ath.cx>
Cc: 493465@bugs.debian.org
Subject: Re: Bug#493465: libncurses5: allocates memory that is never freed
Date: Sat, 2 Aug 2008 21:53:23 -0400 (EDT)
On Sun, 3 Aug 2008, brian m. carlson wrote:

> I personally don't believe refresh is required to work after a
> delwin(stdscr), since
>
>  Calling delwin deletes the named window, freeing all memory associated
>  with it....
>
> except that it doesn't free all the memory associated with it.  It does
> free *some* of it, but not all.  I don't see any possible objection to
> freeing all the related memory in this case, since calling refresh would
> invoke undefined behavior.

looking through the list, I don't see any memory related to delwin which 
is allocated (there are several chunks, and they all appear to be in the 
category covered by --disable-leaks).  Specifically, most of the memory 
allocated by newterm and initscr, since those create more than one window, 
and allocate memory which is not tied to any of those windows.

It _might_ be useful for the Debian debugging library for ncurses to have 
this (disable-leaks) feature enabled.  The drawback is that the behavior 
would differ (as it already does for the tracing functions), and that an 
application would have to call a special function to free the permanent 
mallocs.

-- 
Thomas E. Dickey
http://invisible-island.net
ftp://invisible-island.net




Information forwarded to debian-bugs-dist@lists.debian.org, Daniel Baumann <daniel@debian.org>:
Bug#493465; Package libncurses5. (Fri, 08 May 2009 21:39:05 GMT) Full text and rfc822 format available.

Acknowledgement sent to Lars Doelle <lars.doelle@on-line.de>:
Extra info received and forwarded to list. Copy sent to Daniel Baumann <daniel@debian.org>. (Fri, 08 May 2009 21:39:18 GMT) Full text and rfc822 format available.

Message #30 received at 493465@bugs.debian.org (full text, mbox):

From: Lars Doelle <lars.doelle@on-line.de>
To: 493465@bugs.debian.org
Cc: Thomas Dickey <dickey@his.com>
Subject: Re: Bug#493465: libncurses5: allocates memory that is never freed
Date: Fri, 8 May 2009 23:37:29 +0200
Hi,

i stumbled over this bug, too, and write to ask what the state of resolution is.
The libncurses5-dbg is not distributed with --disable-leaks, at time of writing.

If no semantic issues are know i would suggest not only to build the debugging
library with --disable-leaks, but the production libraries, as well, to allow to build
memory balanced applications and up-stream libraries.

Thanks,

  Lars




Information forwarded to debian-bugs-dist@lists.debian.org, Daniel Baumann <daniel@debian.org>:
Bug#493465; Package libncurses5. (Fri, 08 May 2009 22:03:05 GMT) Full text and rfc822 format available.

Acknowledgement sent to Thomas Dickey <dickey@his.com>:
Extra info received and forwarded to list. Copy sent to Daniel Baumann <daniel@debian.org>. (Fri, 08 May 2009 22:03:05 GMT) Full text and rfc822 format available.

Message #35 received at 493465@bugs.debian.org (full text, mbox):

From: Thomas Dickey <dickey@his.com>
To: Lars Doelle <lars.doelle@on-line.de>, 493465@bugs.debian.org
Cc: debian-bugs-dist@lists.debian.org, Daniel Baumann <daniel@debian.org>
Subject: Re: Bug#493465: libncurses5: allocates memory that is never freed
Date: Fri, 8 May 2009 18:02:02 -0400 (EDT)
On Fri, 8 May 2009, Lars Doelle wrote:

> Hi,
>
> i stumbled over this bug, too, and write to ask what the state of resolution is.
> The libncurses5-dbg is not distributed with --disable-leaks, at time of writing.

--disable-leaks won't (by itself) free "all" leaks.
For that, you'd need the non-public function which frees all memory.

But doing that, some features of ncurses (like any curses implementation)
would not work.  In short the _nc_freeall, etc., are only useful for
debugging, not for a production library.

>
> If no semantic issues are know i would suggest not only to build the debugging
> library with --disable-leaks, but the production libraries, as well, to allow to build
> memory balanced applications and up-stream libraries.
>
> Thanks,
>
>  Lars
>
>
>
>

-- 
Thomas E. Dickey
http://invisible-island.net
ftp://invisible-island.net




Information forwarded to debian-bugs-dist@lists.debian.org, Daniel Baumann <daniel@debian.org>:
Bug#493465; Package libncurses5. (Fri, 15 May 2009 04:39:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Lars Doelle <lars.doelle@on-line.de>:
Extra info received and forwarded to list. Copy sent to Daniel Baumann <daniel@debian.org>. (Fri, 15 May 2009 04:39:03 GMT) Full text and rfc822 format available.

Message #40 received at 493465@bugs.debian.org (full text, mbox):

From: Lars Doelle <lars.doelle@on-line.de>
To: Thomas Dickey <dickey@his.com>
Cc: 493465@bugs.debian.org, debian-bugs-dist@lists.debian.org, Daniel Baumann <daniel@debian.org>
Subject: Re: Bug#493465: libncurses5: allocates memory that is never freed
Date: Fri, 15 May 2009 06:36:32 +0200
Thomas,

(thank you for maintaining ncurses for so long.)


> But doing that, some features of ncurses (like any curses implementation)
> would not work.  In short the _nc_freeall, etc., are only useful for
> debugging, not for a production library.

But this precisely is the point i do not understand. If i call '_nc_freeall' under
the obligation not to call any ncurses routine again, how on earth could this
change the semantics?

Likely, keeping track of the allocated items, as needed for '_nc_freeall' to do
its work, is also something that should be absolutely transparent for the items
themselves. So no semantics should be affected either by the 'debugging'
mode as far as storage is concerned.

So '_nc_freeall' (which is a storage policy thingy, IMO) and semantic changing
debugging features got mixed, or what is it?


Kind regards,
  Lars




Message sent on to "brian m. carlson" <sandals@crustytoothpaste.ath.cx>:
Bug#493465. (Fri, 15 May 2009 23:30:02 GMT) Full text and rfc822 format available.

Message #43 received at 493465-submitter@bugs.debian.org (full text, mbox):

From: Thomas Dickey <dickey@his.com>
To: Lars Doelle <lars.doelle@on-line.de>
Cc: Thomas Dickey <dickey@his.com>, 493465-submitter@bugs.debian.org, Daniel Baumann <daniel@debian.org>
Subject: Re: Bug#493465: libncurses5: allocates memory that is never freed
Date: Fri, 15 May 2009 19:26:40 -0400
[Message part 1 (text/plain, inline)]
On Fri, May 15, 2009 at 06:36:32AM +0200, Lars Doelle wrote:
> Thomas,
> 
> (thank you for maintaining ncurses for so long.)
> 
> 
> > But doing that, some features of ncurses (like any curses implementation)
> > would not work.  In short the _nc_freeall, etc., are only useful for
> > debugging, not for a production library.
> 
> But this precisely is the point i do not understand. If i call '_nc_freeall' under
> the obligation not to call any ncurses routine again, how on earth could this
> change the semantics?

man endwin gives a hint:

       A  program  should  always  call endwin before exiting or escaping from
       curses mode temporarily.  This routine restores tty  modes,  moves  the
       cursor  to the lower left-hand corner of the screen and resets the ter-
       minal into the proper non-visual mode.  Calling refresh or doupdate af-
       ter a temporary escape causes the program to resume visual mode.

(note the "temporarily")

> 
> Likely, keeping track of the allocated items, as needed for '_nc_freeall' to do
> its work, is also something that should be absolutely transparent for the items
> themselves. So no semantics should be affected either by the 'debugging'
> mode as far as storage is concerned.
> 
> So '_nc_freeall' (which is a storage policy thingy, IMO) and semantic changing
> debugging features got mixed, or what is it?
> 
> 
> Kind regards,
>   Lars

-- 
Thomas E. Dickey <dickey@invisible-island.net>
http://invisible-island.net
ftp://invisible-island.net
[signature.asc (application/pgp-signature, inline)]

Message sent on to "brian m. carlson" <sandals@crustytoothpaste.ath.cx>:
Bug#493465. (Sat, 16 May 2009 21:18:09 GMT) Full text and rfc822 format available.

Message #46 received at 493465-submitter@bugs.debian.org (full text, mbox):

From: Lars Doelle <lars.doelle@on-line.de>
To: dickey@his.com
Cc: 493465-submitter@bugs.debian.org, Daniel Baumann <daniel@debian.org>
Subject: Re: Bug#493465: libncurses5: allocates memory that is never freed
Date: Sat, 16 May 2009 23:14:05 +0200
Thomas

> > > But doing that, some features of ncurses (like any curses implementation)
> > > would not work.  In short the _nc_freeall, etc., are only useful for
> > > debugging, not for a production library.
> > 
> > But this precisely is the point i do not understand. If i call '_nc_freeall' under
> > the obligation not to call any ncurses routine again, how on earth could this
> > change the semantics?
> 
> man endwin gives a hint:
> 
>        A  program  should  always  call endwin before exiting or escaping from
>        curses mode temporarily.  This routine restores tty  modes,  moves  the
>        cursor  to the lower left-hand corner of the screen and resets the ter-
>        minal into the proper non-visual mode.  Calling refresh or doupdate af-
>        ter a temporary escape causes the program to resume visual mode.
> 
> (note the "temporarily")

If this means that the semantics is /not/ affected under the obligation /not/ to
issue any other ncurses calls /after/ calling '_nc_freeall', i do not see why this
call cannot be distributed in a production library.

(It is not even distributed in the debugging library, btw. right now, and that alone
would not help much, since everything upstream is properly infected by the
storage policy. E.g.
$ ldd /usr/lib/debug/libreadline.so.5
        libncurses.so.5 => /lib/libncurses.so.5)

Personally, i do not think, this is an issue aside. Right now it is not possible to write
/any/ program providing a non-trivial UI with a balanced memory. This does not
only break the local storage policy (which could demand that all memory is returned
/before/ exit), but also development tools and the development methods. I for one,
prefer to run all my programs with valgrind /while/ developing to detect not only
memory leaks but a lot of other hard to diagnose issues in the moment i introduce
them. Not possible to do that as soon as libncurses get involved. The policy imposed
creeps upstream. See, i add a single call (readline) and get 4 or 5 pages of error
messages in valgrind, covering everything that could of /real/ interest. Ok, i could do
an #ifdef and use getline to test /my/ stuff, but i cannot longer use 'readline' while
developing which only makes life harder for no reason.

Though off-topic, the same issue at precisely the same place under Xlib (mostly
configuration database stuff), successfully preventing any decision whether one
of the graphical programs truly leaks memory or not. Hmm, they almost certainly
all do, and the problem starts with Xlib's memory policy.

It is not that bad with character based UIs, but only because the upstream chain
is shorter. Repeating the summary, it is not possible right now to write /any/
memory balanced program with a decent UI (graphical or character) for a pure
policy issue.

Thomas, i'm well aware that preserving semantics with a thing like curses is a
delicate issue to say the least, but to impose a particular policy (i.e. not to allow
to balance memory before exit) is another to the very best of my understanding.
Thus my asking for any technical reason. If there are non, i vote to include
'_nc_freeall' for production.

As said, though the '_nc_freeall' feature exists (thank you, Thomas), right now it
is not distributed on debian at all, which leaves only to compile a local version.
Thus, technically, it appears to be solved for ncurses, but the solution is simply
not distributed.

 
> > Likely, keeping track of the allocated items, as needed for '_nc_freeall' to do
> > its work, is also something that should be absolutely transparent for the items
> > themselves. So no semantics should be affected either by the 'debugging'
> > mode as far as storage is concerned.
> > 
> > So '_nc_freeall' (which is a storage policy thingy, IMO) and semantic changing
> > debugging features got mixed, or what is it?

Kind regards,
   Lars 




Message sent on to "brian m. carlson" <sandals@crustytoothpaste.ath.cx>:
Bug#493465. (Mon, 18 May 2009 00:57:03 GMT) Full text and rfc822 format available.

Message #49 received at 493465-submitter@bugs.debian.org (full text, mbox):

From: Thomas Dickey <dickey@his.com>
To: Lars Doelle <lars.doelle@on-line.de>
Cc: 493465-submitter@bugs.debian.org, Daniel Baumann <daniel@debian.org>
Subject: Re: Bug#493465: libncurses5: allocates memory that is never freed
Date: Sun, 17 May 2009 20:53:13 -0400 (EDT)
On Sat, 16 May 2009, Lars Doelle wrote:

> Thomas
>
>>>> But doing that, some features of ncurses (like any curses implementation)
>>>> would not work.  In short the _nc_freeall, etc., are only useful for
>>>> debugging, not for a production library.
>>>
>>> But this precisely is the point i do not understand. If i call '_nc_freeall' under
>>> the obligation not to call any ncurses routine again, how on earth could this
>>> change the semantics?
>>
>> man endwin gives a hint:
>>
>>        A  program  should  always  call endwin before exiting or escaping from
>>        curses mode temporarily.  This routine restores tty  modes,  moves  the
>>        cursor  to the lower left-hand corner of the screen and resets the ter-
>>        minal into the proper non-visual mode.  Calling refresh or doupdate af-
>>        ter a temporary escape causes the program to resume visual mode.
>>
>> (note the "temporarily")
>
> If this means that the semantics is /not/ affected under the obligation 
> /not/ to issue any other ncurses calls /after/ calling '_nc_freeall', i 
> do not see why this call cannot be distributed in a production library.

Well, there are several issues - first, being able to discard
most of the memory is necessarily an extension to X/Open.
The description of endwin makes that plain enough (to me, anyway).

But so far, the only use that I'm aware of for this is for analysis -
no real program would be using it.  (memory gets allocated, but doesn't
grow, unless there is a bug ;-)

Then, curses libraries have a variety of higher/lower-level interfaces
(tgetent, setupterm, newterm, initscr), and a lot of legacy applications
that assume things about their behavior.

For debugging, it's sufficient to be able to audit the memory and discard
everything (though not necessarily leave memory in a state that would
permit restarting the library).

Making a cleanup routine a regular part of the API would lead very
quickly to demands that it do-the-right-thing and permit restart.

Not all of the memory can be freed - except in special cases, and then the 
application's dead (such as setbuf).  The check in _nc_free_and_exit 
depends on a special case (a single screen).

>
> (It is not even distributed in the debugging library, btw. right now, and that alone
> would not help much, since everything upstream is properly infected by the
> storage policy. E.g.
> $ ldd /usr/lib/debug/libreadline.so.5
>        libncurses.so.5 => /lib/libncurses.so.5)
>
> Personally, i do not think, this is an issue aside. Right now it is not possible to write
> /any/ program providing a non-trivial UI with a balanced memory. This does not
> only break the local storage policy (which could demand that all memory is returned
> /before/ exit), but also development tools and the development methods. I for one,
> prefer to run all my programs with valgrind /while/ developing to detect not only
> memory leaks but a lot of other hard to diagnose issues in the moment i introduce
> them. Not possible to do that as soon as libncurses get involved. The policy imposed
> creeps upstream. See, i add a single call (readline) and get 4 or 5 pages of error
> messages in valgrind, covering everything that could of /real/ interest. Ok, i could do
> an #ifdef and use getline to test /my/ stuff, but i cannot longer use 'readline' while
> developing which only makes life harder for no reason.

looking at the suppress-files for glibc shows that life is hard to
start with.

(a recent update from Debian got me about a thousand lines of valgrind
warnings in a "clean" program - I suppose it'll get fixed in those
".supp" files ;-).

> Though off-topic, the same issue at precisely the same place under Xlib 
> (mostly configuration database stuff), successfully preventing any 
> decision whether one of the graphical programs truly leaks memory or 
> not. Hmm, they almost certainly all do, and the problem starts with 
> Xlib's memory policy.

I normally get about 4000 lines of listing from running xterm -
with its --disable-leaks option turned on.  Without, that doubles.

>
> It is not that bad with character based UIs, but only because the 
> upstream chain is shorter. Repeating the summary, it is not possible 
> right now to write /any/ memory balanced program with a decent UI 
> (graphical or character) for a pure policy issue.
>
> Thomas, i'm well aware that preserving semantics with a thing like 
> curses is a delicate issue to say the least, but to impose a particular 
> policy (i.e. not to allow to balance memory before exit) is another to 
> the very best of my understanding. Thus my asking for any technical 
> reason. If there are non, i vote to include '_nc_freeall' for 
> production.

>
> As said, though the '_nc_freeall' feature exists (thank you, Thomas), right now it
> is not distributed on debian at all, which leaves only to compile a local version.
> Thus, technically, it appears to be solved for ncurses, but the solution is simply
> not distributed.
>
>
>>> Likely, keeping track of the allocated items, as needed for '_nc_freeall' to do
>>> its work, is also something that should be absolutely transparent for the items
>>> themselves. So no semantics should be affected either by the 'debugging'
>>> mode as far as storage is concerned.
>>>
>>> So '_nc_freeall' (which is a storage policy thingy, IMO) and semantic changing
>>> debugging features got mixed, or what is it?
>
> Kind regards,
>   Lars
>

-- 
Thomas E. Dickey
http://invisible-island.net
ftp://invisible-island.net




Changed Bug submitter to '"brian m. carlson" <sandals@crustytoothpaste.net>' from '"brian m. carlson" <sandals@crustytoothpaste.ath.cx>' Request was from "brian m. carlson" <sandals@crustytoothpaste.net> to control@bugs.debian.org. (Thu, 03 Feb 2011 20:51:30 GMT) Full text and rfc822 format available.

Send a report that this bug log contains spam.


Debian bug tracking system administrator <owner@bugs.debian.org>. Last modified: Thu Apr 17 15:34:04 2014; Machine Name: beach.debian.org

Debian Bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.