From murdoch at stats.uwo.ca  Fri May 22 17:25:22 2009
From: murdoch at stats.uwo.ca (Duncan Murdoch)
Date: Fri, 22 May 2009 11:25:22 -0400
Subject: [Rd] file descriptor leak in getSrcLines in R 2.10.0 svn 48590
In-Reply-To: <77EB52C6DD32BA4D87471DCD70C8D700013DB5FD@NA-PA-VBE03.na.tibco.com>
References: <77EB52C6DD32BA4D87471DCD70C8D70001336538@NA-PA-VBE03.na.tibco.com>
	<4A169CDF.7070007@stats.uwo.ca>
	<77EB52C6DD32BA4D87471DCD70C8D700013DB5FD@NA-PA-VBE03.na.tibco.com>
Message-ID: <4A16C3E2.1000405@stats.uwo.ca>

On 5/22/2009 11:17 AM, William Dunlap wrote:
>> ... 
>> The idea is that if the srcfile is already open, then it 
>> should be left 
>> open; but if it is not open, it should be closed at the end.  
>> open() on 
>> an open srcfile is supposed to make no change to the srcfile, just 
>> return the already open connection.
>> 
>> > (It looks like the srcref stuff is not finished yet, as 
>> there are other
>> > problems, like print(parse(file)) not showing what it used to.)
>> 
>> 
>> This is an encoding problem, which looks easy to fix.  I 
>> think the leak 
>> was caused by this:  because of the encoding problem, the connections 
>> got opened but open.srcfile aborted before completion, so 
>> close.srcfile 
>> didn't think the srcfile was open at all, and it left the 
>> connections in 
>> existence.
> 
> That incompletely opened connection may be why after doing
> this test closeAllConnections crashed R because the ex_ptr
> component of an Rconnection object was a nil pointer:

I saw a crash like that once, but then couldn't reproduce it.  I'll see 
if I can do so with your code.

Duncan Murdoch

> 
>> tf<-tempfile()
>> cat(file=tf, "1:10\nlog(log(pi))\n")
>> p<-parse(tf)
>> p
> expression(<srcref: file "/tmp/RtmpazU79B/file327b23c6" chars 1:1 to 1:4>,
>     <srcref: file "/tmp/RtmpazU79B/file327b23c6" chars 2:1 to 2:12>)
> attr(,"srcfile")
> /tmp/RtmpazU79B/file327b23c6
>> showConnections()
>   description                    class  mode text   isopen   can read can write
> 3 "/tmp/RtmpazU79B/file327b23c6" "file" "rt" "text" "opened" "yes"    "no"
> 4 "/tmp/RtmpazU79B/file327b23c6" "file" "rt" "text" "opened" "yes"    "no"
> 5 "/tmp/RtmpazU79B/file327b23c6" "file" "rt" "text" "opened" "yes"    "no"
> 6 "/tmp/RtmpazU79B/file327b23c6" "file" "rt" "text" "opened" "yes"    "no"
>> closeAllConnections()
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x08118eff in Rf_setAttrib (vec=0x883f278, name=0x8621948, val=0x0)
>     at attrib.c:226
> 226         if (NAMED(val)) val = duplicate(val);
> (gdb) up
> #1  0x08146c7b in do_getconnection (call=0x87a3b74, op=0x85f6fd8,
>     args=0x87a3ca8, env=0x87a3c1c) at connections.c:4166
> 4166            setAttrib(ans, install("conn_id"), con->ex_ptr);
> (gdb) list
> 4161        PROTECT(class = allocVector(STRSXP, 2));
> 4162        SET_STRING_ELT(class, 0, mkChar(con->class));
> 4163        SET_STRING_ELT(class, 1, mkChar("connection"));
> 4164        classgets(ans, class);
> 4165        if (what > 2)
> 4166            setAttrib(ans, install("conn_id"), con->ex_ptr);
> 4167        UNPROTECT(2);
> 4168        return ans;
> 4169    }
> 4170
> 
> (gdb) print con->ex_ptr
> $3 = (void *) 0x0
> (gdb) print *con
> $4 = {class = 0x90c8940 "file",
>   description = 0x89c5878 "/tmp/RtmpazU79B/file327b23c6", enc = 0,
>   mode = "rt\000\000", text = TRUE, isopen = TRUE, incomplete = FALSE,
>   canread = TRUE, canwrite = FALSE, canseek = TRUE, blocking = TRUE,
>   isGzcon = FALSE, open = 0x813c4f2 <file_open>,
>   close = 0x813c77b <file_close>, destroy = 0x813bcf9 <null_destroy>,
>   vfprintf = 0x813c7c3 <file_vfprintf>, fgetc = 0x813bfef <dummy_fgetc>,
>   fgetc_internal = 0x813c860 <file_fgetc_internal>,
>   seek = 0x813c8f9 <file_seek>, truncate = 0x813caa1 <file_truncate>,
>   fflush = 0x813cb8a <file_fflush>, read = 0x813cbae <file_read>,
>   write = 0x813cc26 <file_write>, nPushBack = 0, posPushBack = 64256,
>   PushBack = 0x204, save = -1000, save2 = -1000,
>   encname = "unknown", '\0' <repeats 93 times>, "A", inconv = 0x0,
>   outconv = 0x0,
>   iconvbuff = " \036\022\tE\001\000\000F\001\000\000G\001\000\000H\001\000\000I\001\000\000J",
>   oconvbuff = "\001\000\000K\001\000\000L\001\000\000M\001\000\000N\001\000\000O\001\000\000P\001\000\000Q\001\000\000R\001\000\000S\001\000\000T\001\000\000U\001\000\000V\001", next = 0x157 <Address 0x157 out of bounds>,
>   init_out = "X\001\000\000Y\001\000\000Z\001\000\000[\001\000\000\\\001\000\000]\001\000\000^", navail = 0, inavail = 351, EOF_signalled = 352,
>   UTF8out = FALSE, id = 0x23, ex_ptr = 0x0, private = 0x908ec78}



[Rd] file descriptor leak in getSrcLines in R 2.10.0 svn 48590
Duncan Murdoch