Several folks have previously written that valgrind notices a memory leak in R's readline code. It looks like it leaks a copy of every input line.
% ~/R-svn/r-devel/R/bin/R --debugger=valgrind --debugger-args=--leak-check=full --vanilla ==10725== Memcheck, a memory error detector. ==10725== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. ==10725== Using LibVEX rev 1658, a library for dynamic binary translation. ==10725== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. ==10725== Using valgrind-3.2.1, a dynamic binary instrumentation framework. ==10725== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. ==10725== For more details, rerun with: -v ==10725== R version 2.8.0 Under development (unstable) (2008-07-07 r46046) Type 'q()' to quit R. > invisible("hello") > invisible("hello") > invisible("hello") > invisible("hello") > invisible("hello") > invisible("hello") > invisible("hello") > invisible("hello") > invisible("hello") > invisible("hello") > q() ==10743== ==10743== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 40 from 2) ==10743== malloc/free: in use at exit: 12,591,699 bytes in 5,927 blocks. ==10743== malloc/free: 21,015 allocs, 15,088 frees, 27,744,803 bytes allocated. ==10743== For counts of detected errors, rerun with: -v ==10743== searching for pointers to 5,927 not-freed blocks. ==10743== checked 12,612,676 bytes. ==10743== ==10743== 234 bytes in 13 blocks are definitely lost in loss record 20 of 42 ==10743== at 0x40046EE: malloc (vg_replace_malloc.c:149) ==10743== by 0x68BFF9: xmalloc (in /usr/lib/libreadline.so.4.3) ==10743== by 0x6770D5: readline_internal_teardown (in /usr/lib/libreadline.so.4.3) ==10743== by 0x688992: rl_callback_read_char (in /usr/lib/libreadline.so.4.3) ==10743== by 0x80E739C: Rstd_ReadConsole (sys-std.c:905) ==10743== by 0x8057F61: Rf_ReplIteration (main.c:205) ==10743== by 0x805827E: R_ReplConsole (main.c:306) ==10743== by 0x8058514: run_Rmainloop (main.c:966) ==10743== by 0x805676D: main (Rmain.c:33) ==10743== ==10743== LEAK SUMMARY: ==10743== definitely lost: 234 bytes in 13 blocks. ==10743== possibly lost: 0 bytes in 0 blocks. ==10743== still reachable: 12,591,465 bytes in 5,914 blocks. ==10743== suppressed: 0 bytes in 0 blocks. ==10743== Reachable blocks (those to which a pointer was found) are not shown. ==10743== To see them, rerun with: --show-reachable=yes Some experiments show that the number of blocks leaked from readline_internal_teardown is the number of input lines plus 2 (11+2=13 in this case) and the number of leaked bytes is the total number of bytes in those input lines (including the trailing nulls) plus 40 (10*19+4+40=234 in this case). I think the readline callback function is expected to free its 'char *line' argument. The readline manual says the input line must be freed when using the simple readline() interface but is silent about memory management when using the callback interface. I have not looked in the readline source code. See http://www.mail-archive.com/[EMAIL PROTECTED]/msg04863.html for a same problem in other software using readline: > Are you sure about this? Does readline really expect callback to free > the line? (and if it does, can it be bug in the specific readline > version you are using?) > - ML A cursory look suggests Elmo is right. That you should free the returned line is explicitly mentioned when using the readline() call: http://www.delorie.com/gnu/docs/readline/rlman_24.html#IDX174 No further mention at the reference for the alternative interface: http://www.delorie.com/gnu/docs/readline/rlman_41.html#IDX288 When I added 'free(line)' to src/unix/sys-std.c:readline_handler() valgrind stopped complaining about the leaks and did not complain about using freed memory. It does start complaining a new leak in the readline code, but it looks like that may be a constant 2 block, 40 byte leak, not something that grows as the session goes on: ==11246== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 40 from 2) ==11246== malloc/free: in use at exit: 12,591,505 bytes in 5,916 blocks. ==11246== malloc/free: 21,015 allocs, 15,099 frees, 27,744,803 bytes allocated. ==11246== For counts of detected errors, rerun with: -v ==11246== searching for pointers to 5,916 not-freed blocks. ==11246== checked 12,612,676 bytes. ==11246== ==11246== 40 bytes in 2 blocks are definitely lost in loss record 10 of 42 ==11246== at 0x40046EE: malloc (vg_replace_malloc.c:149) ==11246== by 0x68BFF9: xmalloc (in /usr/lib/libreadline.so.4.3) ==11246== by 0x68F65B: sh_set_lines_and_columns (in /usr/lib/libreadline.so..3) ==11246== by 0x688AEE: _rl_get_screen_size (in /usr/lib/libreadline.so.4.3) ==11246== by 0x68918C: _rl_init_terminal_io (in /usr/lib/libreadline.so.4.3) ==11246== by 0x677A77: rl_initialize (in /usr/lib/libreadline.so.4.3) ==11246== by 0x6888C6: (within /usr/lib/libreadline.so.4.3) ==11246== by 0x80E7303: Rstd_ReadConsole (sys-std.c:505) ==11246== by 0x8057F61: Rf_ReplIteration (main.c:205) ==11246== by 0x805827E: R_ReplConsole (main.c:306) ==11246== by 0x8058514: run_Rmainloop (main.c:966) ==11246== by 0x805676D: main (Rmain.c:33) ==11246== ==11246== LEAK SUMMARY: ==11246== definitely lost: 40 bytes in 2 blocks. ==11246== possibly lost: 0 bytes in 0 blocks. ==11246== still reachable: 12,591,465 bytes in 5,914 blocks. ==11246== suppressed: 0 bytes in 0 blocks. ==11246== Reachable blocks (those to which a pointer was found) are not shown. ==11246== To see them, rerun with: --show-reachable=yes My change is: Index: sys-std.c =================================================================== --- sys-std.c (revision 46046) +++ sys-std.c (working copy) @@ -550,6 +550,7 @@ rl_top->readline_buf[0] = '\n'; rl_top->readline_buf[1] = '\0'; } + free(line) ; rl_top->readline_gotaline = 1; } Here is the info on the session and the shared libraries currently loaded (readline 4.3 in particular): > sessionInfo() R version 2.8.0 Under development (unstable) (2008-07-07 r46046) i686-pc-linux-gnu locale: LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8;LC_COLLATE=en_US.UTF-8;LC_MONETARY=C;LC_MESSAGES=en_US.UTF-8;LC_PAPER=en_US.UTF-8;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=en_US.UTF-8;LC_IDENTIFICATION=C attached base packages: [1] stats graphics grDevices utils datasets methods base > system(paste("pldd", Sys.getpid())) 11304: /homes/bill/R-svn/r-devel/R/bin/exec/R --vanilla /a/homer.insightful.com/users/bill/R-svn/r-devel/R/library/grDevices/libs/grDevices.so /a/homer.insightful.com/users/bill/R-svn/r-devel/R/lib/libRblas.so /usr/lib/libreadline.so.4.3 /lib/ld-2.3.4.so /lib/tls/libc-2.3.4.so /lib/tls/libm-2.3.4.so /lib/libdl-2.3.4.so /lib/libnss_files-2.3.4.so /a/homer.insightful.com/users/bill/R-svn/r-devel/R/library/stats/libs/stats.so /a/homer.insightful.com/users/bill/R-svn/r-devel/R/library/methods/libs/methods.so /lib/libnsl-2.3.4.so /usr/lib/gconv/ISO8859-1.so /lib/libnss_nis-2.3.4.so /usr/lib/libg2c.so.0.0.0 /usr/lib/libncurses.so.5.4 /usr/lib/gconv/gconv-modules.cache /a/homer.insightful.com/users/bill/R-svn/r-devel/R/share/locale/en/LC_MESSAGES/R.mo /usr/lib/locale/locale-archive ---------------------------------------------------------------------------- Bill Dunlap Insightful Corporation bill at insightful dot com 360-428-8146 "All statements in this message represent the opinions of the author and do not necessarily reflect Insightful Corporation policy or position." ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel