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
Pointer ownership with GECreateDevDesc/GEDestroyDevDesc
3 messages · Ritch Melton, Paul Murrell
2 days later
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
1 day later
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/