[Rd] Memory leak

Brahm, David
2006-10-19T15:18:53Z

This is a followup to the R-help thread, "Error: STRING_ELT() can only
be applied to a 'character vector', not a 'builtin'".
Thanks to Prof.
Brian Ripley for suggesting the use of gctorture and valgrind.  I am
getting segmentation faults that appear to come from a memory leak.

I now have a reproducible example (below).  It requires the "g.data"
package (available on CRAN), which contains no C or Fortran code, but
does make extensive use of delayedAssign.  The script was run under
R-2.4.0 (but errors have been occuring through several upgrades) on a
Compaq DL 380-G3 running Red Hat Enterprise Linux 3.0 (i386 32-bit).
I would appreciate any help interpreting the output, or suggesting
followup investigation!

-- David Brahm (brahm at alum.mit.edu)

****************************** Script ********************************

#!/bin/csh
tail +3 "$0" | R -d "/home/a215020/Bin/bin/valgrind
--tool=memcheck
--leak-check=full" --vanilla --slave --args $*; exit
unlink("/tmp/myddp1", recursive=TRUE)
unlink("/tmp/myddp2", recursive=TRUE)
gctorture(TRUE)
require(g.data)
y <- list()
s <- list(tgt="ABCDE", acq="FGHIJ", rat=1, cash=0,
stdt=20051031)
acq.dvd <- tgt.dvd <- NULL
dts <-
c(20051031,20051101,20051102,20051103,20051104,20051107,20051108,2005110
9,20051110)

g.data.attach("/tmp/myddp1")
assign("id.ric", c("ABCDE","FGHIJ",
letters[1:16]), 2)
assign("id.dvd", rep(0, 18), 2)
assign("tm.time", 1:392, 2)
assign("bid", matrix(1, 392, 18, dimnames=list(NULL, id.ric)), 2)
assign("ask", matrix(2, 392, 18, dimnames=list(NULL, id.ric)), 2)
g.data.save()
detach(2)

g.data.attach("/tmp/myddp2")
assign("id.ric", letters[1:18], 2)
g.data.save()
detach(2)

for (date in dts) {
    cat(date, "\n")
    cat("debug2\n")
    ii <- (match(date, dts)-1) %% 2 + 1
    g.data.attach(paste("/tmp/myddp", ii, sep=""))
    if (!all(c(s$tgt, s$acq) %in% id.ric)) {detach(2); next}
    k <- paste(substring(date, c(5,7,3), c(6,8,4)), collapse="/")
    cat("debug3\n")
    acq.dvd[k] <- id.dvd[s$acq]
    tgt.dvd[k] <- id.dvd[s$tgt]
    qt <- tm.time >= 5 & tm.time <= 388
    tms <- tm.time[qt]
    cat("debug4\n")
    y[[k]] <- bid[qt,s$acq] * s$rat + s$cash - ask[qt,s$tgt]
    cat("debug5\n")
    detach(2)
}
cat("done\n")

****************************** Output ********************************

==11423== Memcheck, a memory error detector.
==11423== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et
al.
==11423== Using LibVEX rev 1658, a library for dynamic binary
translation.
==11423== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==11423== Using valgrind-3.2.1, a dynamic binary instrumentation
framework.
==11423== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et
al.
==11423== For more details, rerun with: -v
==11423==
Loading required package: g.data
[1] TRUE
Warning message:
'g.data.save' will create: /tmp/myddp1
 in: g.data.attach("/tmp/myddp1")
Warning message:
'g.data.save' will create: /tmp/myddp2
 in: g.data.attach("/tmp/myddp2")
20051031
debug2
debug3
debug4
debug5
20051101
debug2
20051102
debug2
debug3
debug4
debug5
20051103
debug2
20051104
debug2
debug3
debug4
debug5
20051107
debug2
20051108
debug2
debug3
debug4
debug5
20051109
debug2
20051110
debug2
debug3
==11423== Invalid read of size 1
==11423==    at 0x80F1390: SETCAR (memory.c:2626)
==11423==    by 0x80C1617: R_HashSet (envir.c:219)
==11423==    by 0x80C2CC1: Rf_defineVar (envir.c:1261)
==11423==    by 0x814F6BE: RestoreToEnv (saveload.c:2043)
==11423==    by 0x8150465: do_loadFromConn2 (saveload.c:2358)
==11423==    by 0x80F95FF: do_internal (names.c:1097)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CCAC1: do_begin (eval.c:1107)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CB5E0: Rf_applyClosure (eval.c:614)
==11423==    by 0x80CB1B7: Rf_eval (eval.c:455)
==11423==    by 0x80CCAC1: do_begin (eval.c:1107)
==11423==  Address 0x473D163 is 3 bytes inside a block of size 168
free'd
==11423==    at 0x401B2A3: free (vg_replace_malloc.c:233)
==11423==    by 0x80ED27C: ReleaseLargeFreeVectors (memory.c:759)
==11423==    by 0x80EED30: RunGenCollect (memory.c:1351)
==11423==    by 0x80F0635: R_gc_internal (memory.c:2141)
==11423==    by 0x80F000C: Rf_allocVector (memory.c:1942)
==11423==    by 0x814F67A: RestoreToEnv (saveload.c:2038)
==11423==    by 0x8150465: do_loadFromConn2 (saveload.c:2358)
==11423==    by 0x80F95FF: do_internal (names.c:1097)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CCAC1: do_begin (eval.c:1107)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CB5E0: Rf_applyClosure (eval.c:614)
==11423==
==11423== Invalid read of size 1
==11423==    at 0x80EF3B8: RunGenCollect (memory.c:1240)
==11423==    by 0x80F0635: R_gc_internal (memory.c:2141)
==11423==    by 0x80EFD25: Rf_cons (memory.c:1732)
==11423==    by 0x80CDA44: Rf_promiseArgs (eval.c:1551)
==11423==    by 0x80CB19A: Rf_eval (eval.c:454)
==11423==    by 0x80A198B: Rf_endcontext (context.c:241)
==11423==    by 0x80CB57C: Rf_applyClosure (eval.c:617)
==11423==    by 0x80CB1B7: Rf_eval (eval.c:455)
==11423==    by 0x80CCAC1: do_begin (eval.c:1107)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CB5E0: Rf_applyClosure (eval.c:614)
==11423==    by 0x80CB1B7: Rf_eval (eval.c:455)
==11423==  Address 0x473D163 is 3 bytes inside a block of size 168
free'd
==11423==    at 0x401B2A3: free (vg_replace_malloc.c:233)
==11423==    by 0x80ED27C: ReleaseLargeFreeVectors (memory.c:759)
==11423==    by 0x80EED30: RunGenCollect (memory.c:1351)
==11423==    by 0x80F0635: R_gc_internal (memory.c:2141)
==11423==    by 0x80F000C: Rf_allocVector (memory.c:1942)
==11423==    by 0x814F67A: RestoreToEnv (saveload.c:2038)
==11423==    by 0x8150465: do_loadFromConn2 (saveload.c:2358)
==11423==    by 0x80F95FF: do_internal (names.c:1097)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CCAC1: do_begin (eval.c:1107)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CB5E0: Rf_applyClosure (eval.c:614)
==11423==
==11423== Invalid write of size 1
==11423==    at 0x80EF3C2: RunGenCollect (memory.c:1240)
==11423==    by 0x80F0635: R_gc_internal (memory.c:2141)
==11423==    by 0x80EFD25: Rf_cons (memory.c:1732)
==11423==    by 0x80CDA44: Rf_promiseArgs (eval.c:1551)
==11423==    by 0x80CB19A: Rf_eval (eval.c:454)
==11423==    by 0x80A198B: Rf_endcontext (context.c:241)
==11423==    by 0x80CB57C: Rf_applyClosure (eval.c:617)
==11423==    by 0x80CB1B7: Rf_eval (eval.c:455)
==11423==    by 0x80CCAC1: do_begin (eval.c:1107)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CB5E0: Rf_applyClosure (eval.c:614)
==11423==    by 0x80CB1B7: Rf_eval (eval.c:455)
==11423==  Address 0x473D163 is 3 bytes inside a block of size 168
free'd
==11423==    at 0x401B2A3: free (vg_replace_malloc.c:233)
==11423==    by 0x80ED27C: ReleaseLargeFreeVectors (memory.c:759)
==11423==    by 0x80EED30: RunGenCollect (memory.c:1351)
==11423==    by 0x80F0635: R_gc_internal (memory.c:2141)
==11423==    by 0x80F000C: Rf_allocVector (memory.c:1942)
==11423==    by 0x814F67A: RestoreToEnv (saveload.c:2038)
==11423==    by 0x8150465: do_loadFromConn2 (saveload.c:2358)
==11423==    by 0x80F95FF: do_internal (names.c:1097)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CCAC1: do_begin (eval.c:1107)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CB5E0: Rf_applyClosure (eval.c:614)
==11423==
==11423== Invalid read of size 4
==11423==    at 0x80EF3C5: RunGenCollect (memory.c:1240)
==11423==    by 0x80F0635: R_gc_internal (memory.c:2141)
==11423==    by 0x80EFD25: Rf_cons (memory.c:1732)
==11423==    by 0x80CDA44: Rf_promiseArgs (eval.c:1551)
==11423==    by 0x80CB19A: Rf_eval (eval.c:454)
==11423==    by 0x80A198B: Rf_endcontext (context.c:241)
==11423==    by 0x80CB57C: Rf_applyClosure (eval.c:617)
==11423==    by 0x80CB1B7: Rf_eval (eval.c:455)
==11423==    by 0x80CCAC1: do_begin (eval.c:1107)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CB5E0: Rf_applyClosure (eval.c:614)
==11423==    by 0x80CB1B7: Rf_eval (eval.c:455)
==11423==  Address 0x473D168 is 8 bytes inside a block of size 168
free'd
==11423==    at 0x401B2A3: free (vg_replace_malloc.c:233)
==11423==    by 0x80ED27C: ReleaseLargeFreeVectors (memory.c:759)
==11423==    by 0x80EED30: RunGenCollect (memory.c:1351)
==11423==    by 0x80F0635: R_gc_internal (memory.c:2141)
==11423==    by 0x80F000C: Rf_allocVector (memory.c:1942)
==11423==    by 0x814F67A: RestoreToEnv (saveload.c:2038)
==11423==    by 0x8150465: do_loadFromConn2 (saveload.c:2358)
==11423==    by 0x80F95FF: do_internal (names.c:1097)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CCAC1: do_begin (eval.c:1107)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CB5E0: Rf_applyClosure (eval.c:614)
==11423==
==11423== Invalid read of size 4
==11423==    at 0x80EF3C8: RunGenCollect (memory.c:1240)
==11423==    by 0x80F0635: R_gc_internal (memory.c:2141)
==11423==    by 0x80EFD25: Rf_cons (memory.c:1732)
==11423==    by 0x80CDA44: Rf_promiseArgs (eval.c:1551)
==11423==    by 0x80CB19A: Rf_eval (eval.c:454)
==11423==    by 0x80A198B: Rf_endcontext (context.c:241)
==11423==    by 0x80CB57C: Rf_applyClosure (eval.c:617)
==11423==    by 0x80CB1B7: Rf_eval (eval.c:455)
==11423==    by 0x80CCAC1: do_begin (eval.c:1107)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CB5E0: Rf_applyClosure (eval.c:614)
==11423==    by 0x80CB1B7: Rf_eval (eval.c:455)
==11423==  Address 0x473D16C is 12 bytes inside a block of size 168
free'd
==11423==    at 0x401B2A3: free (vg_replace_malloc.c:233)
==11423==    by 0x80ED27C: ReleaseLargeFreeVectors (memory.c:759)
==11423==    by 0x80EED30: RunGenCollect (memory.c:1351)
==11423==    by 0x80F0635: R_gc_internal (memory.c:2141)
==11423==    by 0x80F000C: Rf_allocVector (memory.c:1942)
==11423==    by 0x814F67A: RestoreToEnv (saveload.c:2038)
==11423==    by 0x8150465: do_loadFromConn2 (saveload.c:2358)
==11423==    by 0x80F95FF: do_internal (names.c:1097)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CCAC1: do_begin (eval.c:1107)
==11423==    by 0x80CB320: Rf_eval (eval.c:431)
==11423==    by 0x80CB5E0: Rf_applyClosure (eval.c:614)
==11423==

<********** (lots more of the same deleted - DB) ************>

==11423== More than 100 errors detected.  Subsequent errors
==11423== will still be recorded, but in less detail than before.
debug4
debug5
done
==11423==
==11423== ERROR SUMMARY: 3173 errors from 100 contexts (suppressed: 43
from 2)
==11423== malloc/free: in use at exit: 12,199,229 bytes in 5,842 blocks.
==11423== malloc/free: 83,926 allocs, 78,084 frees, 75,199,703 bytes
allocated.
==11423== For counts of detected errors, rerun with: -v
==11423== searching for pointers to 5,842 not-freed blocks.
==11423== checked 12,108,392 bytes.
==11423==
==11423==
==11423== 35 bytes in 1 blocks are definitely lost in loss record 9 of
34
==11423==    at 0x401A6EE: malloc (vg_replace_malloc.c:149)
==11423==    by 0x816E183: Rf_InitTempDir (sysutils.c:589)
==11423==    by 0x80EAF47: setup_Rmainloop (main.c:724)
==11423==    by 0x80EB52A: Rf_mainloop (main.c:933)
==11423==    by 0x8068381: main (Rmain.c:33)
==11423==
==11423==
==11423== 468 bytes in 22 blocks are definitely lost in loss record 16
of 34
==11423==    at 0x401A6EE: malloc (vg_replace_malloc.c:149)
==11423==    by 0x806B7C8: Putenv (Renviron.c:130)
==11423==    by 0x806B9A5: process_Renviron (Renviron.c:192)
==11423==    by 0x806BAB5: process_system_Renviron (Renviron.c:225)
==11423==    by 0x8174F1A: Rf_initialize_R (system.c:223)
==11423==    by 0x806837C: main (Rmain.c:32)
==11423==
==11423== LEAK SUMMARY:
==11423==    definitely lost: 503 bytes in 23 blocks.
==11423==      possibly lost: 0 bytes in 0 blocks.
==11423==    still reachable: 12,198,726 bytes in 5,819 blocks.
==11423==         suppressed: 0 bytes in 0 blocks.
==11423== Reachable blocks (those to which a pointer was found) are not
shown.
==11423== To see them, rerun with: --show-reachable=yes