[Rd] reproducible segmentation fault caused by textConnection()

Prof Brian Ripley ripley at stats.ox.ac.uk
Thu May 1 14:42:38 CEST 2008


Bill,

Thanks for digging into this -- I am getting much less information from 
valgrind, even running an instrumented R build.

The issue is specific to using textConnection(NULL, open='w'), which 
really isn't very useful -- that is what anonymous file() connections are 
for, as the help page says.

However, I have found the cause, and have a fix under testing.  Assuming 
nothing else comes to light it will get committed to R-patched today.

Brian

On Tue, 29 Apr 2008, Bill Dunlap wrote:

> If you call gctorture(TRUE) the error happens immediately,
> at the same place.
>    2064                PROTECT(tmp = lengthgets(this->data, ++this->len));
>
> Is this a case where PROTECT_WITH_INDEX() and REPROTECT()
> need to be used (in connections.c)?  Could lengthgets (used
> by the SET_LENGTH() macro) be changed to propogate the protection
> status?  It looks like it always requires protection tricks
> to use.

AFAICS that is not where the issue is.  this->data is protected if linked 
to a variable, but not otherwise.  Certainly on my system it has been 
gc-ed prior to that line.

> 	Bill
>
> On Tue, 29 Apr 2008, Bill Dunlap wrote:
>
>> On Tue, 29 Apr 2008, Gregoire Pau wrote:
>>
>>> Dear all,
>>>
>>> It seems that textConnection() can trigger a segmentation fault. The
>>> following script (using two large loops) makes this bug reproducible:
>>>
>>> for (i in 1:10000) {
>>>    z=textConnection(NULL,open='w')
>>>    for (j in 1:100) {
>>>      write(runif(1)*1e6,file=z)
>>>      write('\n',file=z)
>>>    }
>>>    close(z)
>>> }
>>>
>>> The bug could be reproduced on R-2.6.1, R-2.7.0 and on the latest
>>> R-devel 2008-04-29 r45543.
>>
>> valgrind shows that it uses freed memory after
>> a garbage collecting episode (after many iterations),
>> because a Routtextconn's 'data' component was freed:
>>
>>    ==24210== Invalid read of size 1
>>    ==24210==    at 0x810B328: Rf_lengthgets (Rinlinedfuns.h:358)
>>    ==24210==    by 0x8121C48: text_vfprintf (connections.c:2064)
>>    ==24210==    by 0x809D0C1: Rvprintf (printutils.c:770)
>>    ==24210==    by 0x809D105: Rprintf (printutils.c:668)
>>    ==24210==    by 0x810A984: do_cat (builtin.c:617)
>>    ==24210==  Address 0x5823CD8 is 0 bytes inside a block of size 1,176 free'd
>>    ==24210==    at 0x40052A3: free (vg_replace_malloc.c:233)
>>    ==24210==    by 0x805AC3D: R_gc_internal (memory.c:769)
>>    ==24210==    by 0x805B873: Rf_cons (memory.c:1757)
>>    ==24210==    by 0x81571F6: Rf_promiseArgs (eval.c:1633)
>>
>>    (gdb) where 5
>>    #0  Rf_lengthgets (x=0x5823cd8, len=289)
>>        at ../../src/include/Rinlinedfuns.h:358
>>    #1  0x08121c49 in text_vfprintf (con=0x500f280, format=0x81e64d8 "\n",
>>     ap=0xbef18b84 "?\213??") at connections.c:2064
>>    #2  0x0809d0c2 in Rvprintf (format=0x81e64d8 "\n", arg=0xbef18b84 "?\213??")
>>        at printutils.c:770
>>    #3  0x0809d106 in Rprintf (format=0x81e64d8 "\n") at printutils.c:668
>>    #4  0x0810a985 in do_cat (call=0x4ae31f0, op=0x4104eec, args=0x55bb2bc,
>>        rho=0x55baf20) at builtin.c:617
>>    (More stack frames follow...)
>>    (gdb) up
>>    #1  0x08121c49 in text_vfprintf (con=0x500f280, format=0x81e64d8 "\n",
>>        ap=0xbef18b84 "?\213??") at connections.c:2064
>>    2064                PROTECT(tmp = lengthgets(this->data, ++this->len));
>>    (gdb) print this->data
>>    $1 = 0x5823cd8
>>    (gdb) whatis this
>>    type = Routtextconn
>>    (gdb) whatis this->data
>>    type = SEXP
>>    (gdb) print *this->data
>>    $2 = {sxpinfo = {type = 16, obj = 0, named = 2, gp = 0, mark = 0, debug = 0,
>>      trace = 0, spare = 0, gcgen = 0, gccls = 7}, attrib = 0x40ae088,
>>      gengc_next_node = 0x8235270, gengc_prev_node = 0x8235270, u = {primsxp = {
>>      offset = 288}, symsxp = {pname = 0x120, value = 0x0,
>>      internal = 0x57685c0}, listsxp = {carval = 0x120, cdrval = 0x0,
>>      tagval = 0x57685c0}, envsxp = {frame = 0x120, enclos = 0x0,
>>      hashtab = 0x57685c0}, closxp = {formals = 0x120, body = 0x0,
>>      env = 0x57685c0}, promsxp = {value = 0x120, expr = 0x0,
>>      env = 0x57685c0}}}
>
> ----------------------------------------------------------------------------
> 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."
>
>

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595



More information about the R-devel mailing list