From wdunlap at tibco.com  Thu Aug  6 23:57:34 2009
From: wdunlap at tibco.com (William Dunlap)
Date: Thu, 6 Aug 2009 14:57:34 -0700
Subject: [Rd] [R] Repeatable, But Time Varying R GUI Crash (PR#13880)
In-Reply-To: <77EB52C6DD32BA4D87471DCD70C8D7000195E46E@NA-PA-VBE03.na.tibco.com>
References: <20090806204514.8DAE5282EF3D@mail.pubhealth.ku.dk>
	<77EB52C6DD32BA4D87471DCD70C8D7000195E46E@NA-PA-VBE03.na.tibco.com>
Message-ID: <77EB52C6DD32BA4D87471DCD70C8D7000195E47D@NA-PA-VBE03.na.tibco.com>

The following change to src/main/saveload.c seems to fix
the problem.  (I think problem2() has gotten past the place where
valgrind first complained, but it will be quite a while before it
is done.)  It just protects 'ans' before 'names' is allocated instead
of afterwards.

===================================================================
--- saveload.c  (revision 49063)
+++ saveload.c  (working copy)
@@ -2012,11 +2012,12 @@
     if (! isList(ans))
        error(_("loaded data is not in pair list form"));

+    PROTECT(ans);
     a = ans;
     while (a != R_NilValue) {a = CDR(a); cnt++;}
     PROTECT(names = allocVector(STRSXP, cnt));
     cnt = 0;
-    PROTECT(a = ans);
+    a = ans;
     while (a != R_NilValue) {
        SET_STRING_ELT(names, cnt++, PRINTNAME(TAG(a)));
        defineVar(TAG(a), CAR(a), aenv);

Bill Dunlap
TIBCO Software Inc - Spotfire Division
wdunlap tibco.com  

> -----Original Message-----
> From: r-devel-bounces at r-project.org 
> [mailto:r-devel-bounces at r-project.org] On Behalf Of William Dunlap
> Sent: Thursday, August 06, 2009 2:37 PM
> To: murdoch at stats.uwo.ca; r-devel at stat.math.ethz.ch
> Cc: R-bugs at r-project.org
> Subject: Re: [Rd] [R] Repeatable, But Time Varying R GUI 
> Crash (PR#13880)
> 
> > -----Original Message-----
> > From: r-devel-bounces at r-project.org 
> > [mailto:r-devel-bounces at r-project.org] On Behalf Of 
> > murdoch at stats.uwo.ca
> > Sent: Thursday, August 06, 2009 1:45 PM
> > To: r-devel at stat.math.ethz.ch
> > Cc: R-bugs at r-project.org
> > Subject: Re: [Rd] [R] Repeatable, But Time Varying R GUI 
> > Crash (PR#13880)
> > 
> > On 8/6/2009 4:11 PM, Marilyn & Rich Short wrote:
> > > Hello,
> > > 
> > > I'm having a problem in R. The R GUI is crashing with a 
> message to 
> > > contact Microsoft for the solution. I've contacted 
> > Microsoft and they 
> > > are of no help. Below is a distilled set of code that will 
> > cause the 
> > > crash. As you will see, there are two do-loops within which 
> > is a "load" 
> > > command. The crash usually occurs after 200*400 (=80,000) to 
> > > 2,000*400(=800,000) iterations.
> > > 
> > > Do you have any suggestions on work-arounds?
> > 
> > I can confirm it in R-patched as well.  It happens on the 
> very first 
> > time through if you set gctorture() on, so it looks like 
> somewhere in 
> > there is a missing PROTECT, and the garbage collector is reclaiming 
> > something that it shouldn't.
> > 
> > I'll try to track it down, but I'm not sure how quick I'll be.
> 
> On Linux with R-2.10.0(devel) valgrind shows:
> > gctorture()
> > problem2()
> ==9777== Invalid read of size 1
> ==9777==    at 0x805DD5C: SETCAR (memory.c:2712)
> ==9777==    by 0x8156463: Rf_defineVar (envir.c:1353)
> ==9777==    by 0x80B3B16: RestoreToEnv (saveload.c:2022)
> ==9777==    by 0x80B4913: do_loadFromConn2 (saveload.c:2346)
> ==9777==    by 0x8065CF4: do_internal (names.c:1160)
> ==9777==    by 0x816629F: Rf_eval (eval.c:464)
> ==9777==    by 0x816815D: do_begin (eval.c:1244)
> ==9777==    by 0x816629F: Rf_eval (eval.c:464)
> ==9777==    by 0x8169853: Rf_applyClosure (eval.c:698)
> ==9777==    by 0x81661D7: Rf_eval (eval.c:508)
> ==9777==    by 0x816815D: do_begin (eval.c:1244)
> ==9777==    by 0x816629F: Rf_eval (eval.c:464)
> ==9777==  Address 0x4516A1B is 3 bytes inside a block of size 2,584
> free'd
> ==9777==    at 0x40052A3: free (vg_replace_malloc.c:233)
> ==9777==    by 0x805B121: R_gc_internal (memory.c:784)
> ==9777==    by 0x805C1CF: Rf_allocVector (memory.c:2022)
> ==9777==    by 0x80B3AD2: RestoreToEnv (saveload.c:2017)
> ==9777==    by 0x80B4913: do_loadFromConn2 (saveload.c:2346)
> ==9777==    by 0x8065CF4: do_internal (names.c:1160)
> ==9777==    by 0x816629F: Rf_eval (eval.c:464)
> ==9777==    by 0x816815D: do_begin (eval.c:1244)
> ==9777==    by 0x816629F: Rf_eval (eval.c:464)
> ==9777==    by 0x8169853: Rf_applyClosure (eval.c:698)
> ==9777==    by 0x81661D7: Rf_eval (eval.c:508)
> ==9777==    by 0x816815D: do_begin (eval.c:1244)
> ==9777==
> ==9777== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- y
> starting debugger
> ==9777== starting debugger with cmd: /usr/bin/gdb -nw 
> /proc/9802/fd/1014
> 9802
> GNU gdb Red Hat Linux (6.3.0.0-1.96rh)
> Copyright 2004 Free Software Foundation, Inc.
> GDB is free software, covered by the GNU General Public 
> License, and you
> are
> welcome to change it and/or distribute copies of it under certain
> conditions.
> Type "show copying" to see the conditions.
> There is absolutely no warranty for GDB.  Type "show warranty" for
> details.
> This GDB was configured as "i386-redhat-linux-gnu"...Using host
> libthread_db library "/lib/tls/libthread_db.so.1".
> 
> Attaching to program: /proc/9802/fd/1014, process 9802
> SETCAR (x=0x5565da0, y=0x4516a18) at memory.c:2712
> 2712        CHECK_OLD_TO_NEW(x, y);
> (gdb) up
> #1  0x08156464 in Rf_defineVar (symbol=0x4f5eee0, value=0x4516a18,
>     rho=0x559a77c) at envir.c:1353
> 1353                        SET_BINDING_VALUE(frame, value);
> (gdb) list
> 1348            if (HASHTAB(rho) == R_NilValue) {
> 1349                /* First check for an existing binding */
> 1350                frame = FRAME(rho);
> 1351                while (frame != R_NilValue) {
> 1352                    if (TAG(frame) == symbol) {
> 1353                        SET_BINDING_VALUE(frame, value);
> 1354                        SET_MISSING(frame, 0);      /* 
> Over-ride */
> 1355                        return;
> 1356                    }
> 1357                    frame = CDR(frame);
> (gdb) up
> #2  0x080b3b17 in RestoreToEnv (ans=0x54876b4, aenv=0x559a77c)
>     at saveload.c:2022
> 2022            defineVar(TAG(a), CAR(a), aenv);
> (gdb) list
> 2017        PROTECT(names = allocVector(STRSXP, cnt));
> 2018        cnt = 0;
> 2019        PROTECT(a = ans);
> 2020        while (a != R_NilValue) {
> 2021            SET_STRING_ELT(names, cnt++, PRINTNAME(TAG(a)));
> 2022            defineVar(TAG(a), CAR(a), aenv);
> 2023            if(R_seemsOldStyleS4Object(CAR(a)))
> 2024                warningcall(R_NilValue,
> 2025                            _("'%s' looks like a pre-2.4.0 S4
> object: please recreate it"),
> 2026                            CHAR(PRINTNAME(TAG(a))));
> 
> It again complains about the call to R_seemsOldStyleS4Object().
> 
> Memory in 'a' may have been freed.  Shouldn't the
>     PROTECT(a=ans)
> be done earlier, when ans is allocated, instead of when
> the pointer is copied?
> 
> 
> Bill Dunlap
> TIBCO Software Inc - Spotfire Division
> wdunlap tibco.com 
> 
> >  (My 
> > house is full of contractors right now, so not a very nice 
> > place to work.)
> > 
> > I don't know any workaround other than "avoid doing the 
> buggy thing". 
> > But I can't tell you what that is....
> > 
> > Duncan Murdoch
> > 
> > > Once you start the function with the  "problem2()" command, 
> > the function 
> > > will print to the screen once every 400 iterations. You can 
> > monitor the 
> > > progress by clicking the scroll button. The R GUI should 
> > crash somewhere 
> > > between i=200 and i=2000. Although the problem is 
> > repeatable, the time 
> > > at which the crash occurs is random.
> > > 
> > > Thanks in advance for your attention,
> > > 
> > > Rich Short
> > > 
> > > I'm using Windows XP, SP3 and R 2.9.1.
> > > Here is my session info:
> > > 
> > >> sessionInfo()
> > > R version 2.9.1 (2009-06-26)
> > > i386-pc-mingw32
> > > 
> > > locale:
> > > LC_COLLATE=English_United States.1252;LC_CTYPE=English_United
> > > States.1252;LC_MONETARY=English_United
> > > States.1252;LC_NUMERIC=C;LC_TIME=English_United States.1252
> > > 
> > > attached base packages:
> > > [1] stats     graphics  grDevices utils     datasets  
> methods   base
> > > 
> > > (The problem occurs on my Vista machine as well.)
> > > *******************************************
> > > 
> > > # This script induces the R GUI to crash.
> > > 
> > > problem2 = function(){
> > > 
> > > junk = mat.or.vec(8,40)
> > > 
> > > junk[] = 1
> > > 
> > > mjunk = mat.or.vec(8,40)
> > > 
> > > mjunk[] = -1
> > > 
> > > PathA = tempdir()
> > > 
> > > conX = paste(PathA,"junkx",sep="\\")
> > > 
> > > conY = paste(PathA,"junky",sep="\\")
> > > 
> > > outJunk = file(conX, open="wb")
> > > 
> > > save(junk, file=outJunk)
> > > 
> > > close(outJunk)
> > > 
> > > outJunkY = file(conY, open="wb")
> > > 
> > > save(mjunk, file=outJunkY)
> > > 
> > > close(outJunkY)
> > > 
> > > sign = 1
> > > 
> > > for(i in 1:4000){
> > > 
> > > for(ii in 1:400){
> > > 
> > > sign = -sign
> > > 
> > > if(sign<0){
> > > 
> > > load(file=conX)
> > > 
> > > }else{
> > > 
> > > load(file=conY)
> > > 
> > > }
> > > 
> > > sum = junk[1,5] + mjunk[3,30]
> > > 
> > > }
> > > 
> > > cat(" junk = ",junk[1,5],sep="")
> > > 
> > > cat(" mjunk = ",mjunk[3,30],sep="")
> > > 
> > > cat(" sum = ",sum,sep="")
> > > 
> > > cat(" i = ",i,"\n",sep="")
> > > 
> > > }
> > > 
> > > }
> > > 
> > > ______________________________________________
> > > R-help at r-project.org mailing list
> > > https://stat.ethz.ch/mailman/listinfo/r-help
> > > PLEASE do read the posting guide 
> > http://www.R-project.org/posting-guide.html
> > > and provide commented, minimal, self-contained, reproducible code.
> > 
> > ______________________________________________
> > R-devel at r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
> > 
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 



[Rd] [R] Repeatable, But Time Varying R GUI Crash (PR#13880)
William Dunlap