From paul at stat.auckland.ac.nz  Wed Sep 24 05:54:04 2014
From: paul at stat.auckland.ac.nz (Paul Murrell)
Date: Wed, 24 Sep 2014 15:54:04 +1200
Subject: [Rd] Pointer ownership with GECreateDevDesc/GEDestroyDevDesc
In-Reply-To: <CAHXt8XH8FAQRTDpx0z=wtoeuoqEk-XdVVSXu994M0DNLs64MSw@mail.gmail.com>
References: <CAHXt8XEbZRW=+hdF64Z_Oc+4s_VEqsa0+MnWy1b=nUcLmhmjaQ@mail.gmail.com>
	<CAHXt8XH8FAQRTDpx0z=wtoeuoqEk-XdVVSXu994M0DNLs64MSw@mail.gmail.com>
Message-ID: <5422405C.90208@stat.auckland.ac.nz>


This seems like the best solution (free and NULL the dev pointer in 
dev_Close(), BEFORE GEdestroyDevDesc() has a go).

I think this should be safe because dev_Close() and GEdestroyDevDesc() 
are only called in one place (so your free() should always happen before 
GEdestroyDevDesc() and your free() shouldn't happen in any other, 
potentially inappropriate, context).

Paul

On 09/23/14 03:15, Ritch Melton wrote:
> I perused the source for RStudio and noticed that they had a similar
> problem. I didn't think that the GEDevDesc structure was exported, but
> apparently this is a worthwhile workaround to the defect.
>
> void GD_Close(pDevDesc dev)
> {
> ...elided...
>        // explicitly free and then null out the dev pointer of the GEDevDesc
>        // This is to avoid incompatabilities between the heap we are
> compiled with
>        // and the heap R is compiled with (we observed this to a problem with
>        // 64-bit R)
>        std::free(s_pGEDevDesc->dev);
>        s_pGEDevDesc->dev = NULL;
>
>        // set GDDevDesc to NULL so we don't reference it again
>        s_pGEDevDesc = NULL;
>     }
> }
>
> I will
>
> On Fri, Sep 19, 2014 at 10:37 AM, Ritch Melton <skyguy94 at gmail.com> wrote:
>
>> According to the "R Internals" document, for a custom device, I should
>> create a pDevDesc structure that gets passed to GECreateDevDesc.
>>
>> ..elided...
>> pDevDesc dev;
>> /* Allocate and initialize the device driver data */
>> if (!(dev = (pDevDesc) calloc(1, sizeof(DevDesc)))) return 0;
>> /* or error() */
>> /* set up device driver or free ?dev? and error() */
>> gdd = GEcreateDevDesc(dev); GEaddDevice2(gdd, "dev_name");
>> ...elided...
>>
>> which indicates to me that the calling code owns the pDevDesc structure
>> and should be responsible for freeing it.
>> However, in GEdestroyDevDesc, that particular code calls free(dd->dev),
>> freeing the pointer.
>>
>> In my case, I have a device implemented and created in a language that is
>> using a different allocator. The pDevDesc I pass in is not owned by R and
>> causes a crash on free with "dev.off()".
>>
>> I thought I could mitigate the issue, by making a call to the allocator R
>> is using via an exported R function, such as R_alloc, but I did not see
>> such a function available to me.
>>
>> I would like to know if I should be creating the pDevDesc via an imported
>> alloc routine somehow? or is there a way to prevent this code from freeing
>> the structure I pass in.
>>
>> Blue Skies,
>> Ritch
>>
>
> 	[[alternative HTML version deleted]]
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

-- 
Dr Paul Murrell
Department of Statistics
The University of Auckland
Private Bag 92019
Auckland
New Zealand
64 9 3737599 x85392
paul at stat.auckland.ac.nz
http://www.stat.auckland.ac.nz/~paul/



[Rd] Pointer ownership with GECreateDevDesc/GEDestroyDevDesc
Paul Murrell