Skip to content

Segmentation faults on SEXP conversion

6 messages · nabble.30.miller_2555 at spamgourmet.com, Duncan Temple Lang

#
On Sun, Nov 15, 2009 at 2:52 PM, Duncan Murdoch - murdoch at stats.uwo.ca
<+nabble+miller_2555+1412c7fca2.murdoch#stats.uwo.ca at spamgourmet.com>
wrote:
Thank you for the suggestion. I have replaced the code as suggested,
but I had attempted this conversion earlier. Unfortunately, I still
receive the same segmentation fault (and backtrace). The underlying
problem no longer appears to relate to type conversion. The following
code represents the entirety of the extension's R and C code (and
NAMESPACE file), and still causes the segmentation fault:

NAMESPACE:
---------------------------------------------------
useDynLib("tstlib")
export( "ptest" )


ptest.R:
---------------------------------------------------
ptest <- function()  { .Call("Rwrite", PACKAGE="tstlib");};


ptest.c:
---------------------------------------------------
#include <R.h>
void Rwrite() { printf("[%i] %s",12,"Hi"); }


ptest.R:
---------------------------------------------------
ptest <- function()  { .Call("Rwrite", PACKAGE="tstlib");};


zzz.R:
---------------------------------------------------
.onLoad <- function(libname, pkgname)
{
}
.onUnload <- function(libpath) {
    library.dynam.unload("forkex", libpath)
  }


This is just about the most simple example I can think of, and don't
really know why it would segfault (if I change the interface in
ptest.R above from .Call to .C, no segfault occurs). The following is
the output from `R CMD SHLIB ptest.c`:

gcc -m64 -std=gnu99 -I/usr/include/R  -I/usr/local/include    -fpic
-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions
-fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -c
ptest.c -o ptest.o
gcc -m64 -std=gnu99 -shared -L/usr/local/lib64 -o ptest.so ./ptest.o
-L/usr/lib64/R/lib -lR
#
On 15/11/2009 8:25 PM, nabble.30.miller_2555 at spamgourmet.com wrote:
I forget if you said which system you're working on, but it may be that 
you don't have an open file handle for printf to use.  Use Rprintf 
instead and things should be fine.

Duncan Murdoch
#
nabble.30.miller_2555 at spamgourmet.com wrote:
And that is your clue.

C routines that are invoked via .Call() _must_
return a SEXP object. Your routine (Rwrite)
has a return type of void.  Since you use .Call(),
takes the return value from the stack and it is garbage.
Seg fault ensues.

Declare your Rwrite() routine to return a SEXP
and have it return the symbol R_NilValue, i.e.

 SEXP Rwrite() { printf("[%i] %s",12,"Hi"); return(R_NilValue); }

and you can use .Call()


  D.


 D.
#
On Sun, Nov 15, 2009 at 8:30 PM, Duncan Murdoch - murdoch at stats.uwo.ca
<+nabble+miller_2555+1412c7fca2.murdoch#stats.uwo.ca at spamgourmet.com>
wrote:
Thank you - I attempted to use Rprintf as suggested. I also attempted
fprintf() using stdout. The platform is Linux
2.6.27.30-170.2.82.fc10.x86_64. It's a Fedora Core v10. I encountered
the same issue with both R v. 2.9.2 and 2.10.0 (currently running the
latter). If it helps, the following is the memcheck output after
making the suggested changes:
==25809== Invalid read of size 1
==25809==    at 0x4D04209: SET_SYMVALUE (in /usr/lib64/R/lib/libR.so)
==25809==    by 0x4D01E51: Rf_ReplIteration (in /usr/lib64/R/lib/libR.so)
==25809==    by 0x4D020B7: (within /usr/lib64/R/lib/libR.so)
==25809==    by 0x4D027CF: run_Rmainloop (in /usr/lib64/R/lib/libR.so)
==25809==    by 0x40083A: main (in /usr/lib64/R/bin/exec/R)
==25809==  Address 0x3 is not stack'd, malloc'd or (recently) free'd
#
On 15/11/2009 8:25 PM, nabble.30.miller_2555 at spamgourmet.com wrote:
Sorry, I missed something else that's obvious:  .Call needs a return 
value.  The c function needs to include Rinternals.h, and the function 
needs to return a SEXP.  So this works:

#include <Rinternals.h>
SEXP Rwrite() { Rprintf("[%i] %s",12,"Hi");  return R_NilValue; }

(and your ptest function will return NULL).

Duncan Murdoch
#
On Sun, Nov 15, 2009 at 9:16 PM, Duncan Murdoch - murdoch at stats.uwo.ca
<+nabble+miller_2555+1412c7fca2.murdoch#stats.uwo.ca at spamgourmet.com>
wrote:
Ah - I must not have read the documentation closely enough to realize
a return value was required for external functions using the .Call
interface. By not returning anything, I think my erroneous calls were
mangling the stack heap. Thanks!

Will