[Rd] Segfault on ".C" registration via R_CMethodDef according to 'Writing R Extensions'.

From: Daniel Adler <dadler_at_uni-goettingen.de>
Date: Mon, 06 Feb 2012 14:27:59 +0100


Dear R List,

I encountered a serious problem regarding the registration of ".C" when following the documentation "Writing R Extensions" that leads to a segmentation fault (tested on windows and mac os x).

The registration mechanism for ".C" routines via R_registerRoutines and the R_CMethodDef structure has been enhanced recently with the addition of two fields, one for type specification and the other for the style (in, out, inout or irrelevant).

According to the manual 'Writing R Extensions' of version 2.14.1 an example is given that specifies to use the fourth field (type information) for definitions of C routines that use the ".C" calling convention:

R_CMethodDef cMethods[] = {

{"myC", (DL_FUNC) &myC, 4, {REALSXP, INTSXP, STRSXP, LGLSXP}}, /* segfault! */
{NULL, NULL, 0}

};

If I follow this example I get compiler warnings or errors (whether I use C or C++, respectively) and a segmentation fault (in the case of C) when doing R CMD INSTALL, which seem to happen during testing. See build log at the end of this e-mail.

When removing the last field in the initializer list in order to register .C routines in the old way the segfault goes away:

R_CMethodDef cMethods[] = {

{"myC", (DL_FUNC) &myC, 4}, /* works */
{NULL, NULL, 0}

};

There are still warnings/segfault or an error when initializing the undocumented fifth entry (parameter passing style), e.g.

R_CMethodDef cMethods[] = {

{"myC", (DL_FUNC) &myC, 4, {REALSXP, INTSXP, STRSXP, LGLSXP}, {R_ARG_IN, R_ARG_IN, R_ARG_IN, R_ARG_IN}, /* segfault! */
{NULL, NULL, 0}

};

Using a C source, the warnings are:

Using C++, protecting the init/unload function prototypes and structure declarations via 'extern "C" { }', I get the following error:

(line 24 is the point on the entry, while line 30 is the end of the overall array initialization list in C++).

If I put the type and style (unsigned int and enum) arrays separately, the build process works just fine. E.g.

R_NativePrimitiveArgType types[] = {REALSXP, INTSXP, STRSXP, LGLSXP}; R_NativeArgStyle styles[] = { R_ARG_IN, R_ARG_IN, R_ARG_IN, R_ARG_IN };

R_CMethodDef cMethods[] = {

{"myC", (DL_FUNC) &myC, 4, types, NULL}, /* works */
{"myC2", (DL_FUNC) &myC, 4, types, style}, /* works */
{NULL, NULL, 0}

};

(Though I haven't tested the runtime behaviour yet.. but at least no segfault during R CMD INSTALL..)

I wonder what is wrong with the static initializer lists?!

I could imagine it has something to do with the standard compilance of the C/C++ compiler (due to the different behaviour warning or error during compilation).

Anyway, going with the manual right now, the ordinary user will get warnings and errors - at least on the systems that I have tested (recent version of Rtools/Windows 7 and Mac OS X 10.6 with gcc 4.2.1).
On Windows instead of a trace output, a window pops up during install to tell about a process crash.

PS: If it helps, I could put up a test package online for further debugging.

Traceback:

  1. dyn.load(file, DLLpath = DLLpath, ...)
  2. library.dynam(lib, package, package.lib)
  3. loadNamespace(package, c(which.lib.loc, lib.loc))
  4. doTryCatch(return(expr), name, parentenv, handler)
  5. tryCatchOne(expr, names, parentenv, handlers[[1L]])
  6. tryCatchList(expr, classes, parentenv, handlers)
  7. tryCatch(expr, error = function(e) { call <- conditionCall(e) if (!is.null(call)) { if (identical(call[[1L]], quote(doTryCatch))) call <- sys.call(-4L) dcall <- deparse(call)[1L] prefix <- paste("Error in", dcall, ": ") LONG <- 75L msg <- conditionMessage(e) sm <- strsplit(msg, "\n")[[1L]] w <- 14L + nchar(dcall, type = "w") + nchar(sm[1L], type = "w") if (is.na(w)) w <- 14L + nchar(dcall, type = "b") + nchar(sm[1L], type = "b") if (w > LONG) prefix <- paste(prefix, "\n ", sep = "") } else prefix <- "Error : " msg <- paste(prefix, conditionMessage(e), "\n", sep = "") .Internal(seterrmessage(msg[1L])) if (!silent && identical(getOption("show.error.messages"), TRUE)) { cat(msg, file = stderr()) .Internal(printDeferredWarnings()) } invisible(structure(msg, class = "try-error", condition = e))})
  8. try({ ns <- loadNamespace(package, c(which.lib.loc, lib.loc)) dataPath <- file.path(which.lib.loc, package, "data") env <- attachNamespace(ns, pos = pos, dataPath = dataPath, deps)})
  9. library(pkg_name, lib.loc = lib, character.only = TRUE, logical.return = TRUE)
  10. withCallingHandlers(expr, packageStartupMessage = function(c) invokeRestart("muffleMessage"))
  11. suppressPackageStartupMessages(library(pkg_name, lib.loc = lib, character.only = TRUE, logical.return = TRUE))
  12. doTryCatch(return(expr), name, parentenv, handler)
  13. tryCatchOne(expr, names, parentenv, handlers[[1L]])
  14. tryCatchList(expr, classes, parentenv, handlers)
  15. tryCatch(expr, error = function(e) { call <- conditionCall(e) if (!is.null(call)) { if (identical(call[[1L]], quote(doTryCatch))) call <- sys.call(-4L) dcall <- deparse(call)[1L] prefix <- paste("Error in", dcall, ": ") LONG <- 75L msg <- conditionMessage(e) sm <- strsplit(msg, "\n")[[1L]] w <- 14L + nchar(dcall, type = "w") + nchar(sm[1L], type = "w") if (is.na(w)) w <- 14L + nchar(dcall, type = "b") + nchar(sm[1L], type = "b") if (w > LONG) prefix <- paste(prefix, "\n ", sep = "") } else prefix <- "Error : " msg <- paste(prefix, conditionMessage(e), "\n", sep = "") .Internal(seterrmessage(msg[1L])) if (!silent && identical(getOption("show.error.messages"), TRUE)) { cat(msg, file = stderr()) .Internal(printDeferredWarnings()) } invisible(structure(msg, class = "try-error", condition = e))})
  16. try(suppressPackageStartupMessages(library(pkg_name, lib.loc = lib, character.only = TRUE, logical.return = TRUE)))
  17. tools:::.test_load_package("mylib", "/Users/dadler/Library/R/2.14/library") aborting ... sh: line 1: 75200 Bus error '/Library/Frameworks/R.framework/Resources/bin/R' --arch=i386 --no-save --slave < /var/folders/Lr/Lrh7GWILEqCwHkyF1MdauE+++TI/-Tmp-//RtmpDqusSN/file1259d93ec2eb *** arch - x86_64

R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Mon 06 Feb 2012 - 13:29:14 GMT

This quarter's messages: by month, or sorted: [ by date ] [ by thread ] [ by subject ] [ by author ]

All messages

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Mon 06 Feb 2012 - 16:00:14 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.

list of date sections of archive