Yeah, setting R_Interactive is probably fine. I do it (not that I should be considered a "safe" user of R). As to the findFun issue, there is a much more useful function (findVar1 maybe?) that wouldn't die if the object didn't exist.
Sadly, like many functions useful for the development of user interfaces and embedding R have been marked "hidden" making them unavailable for use without building a custom version of R. On 7/4/07, Joe Conway <[EMAIL PROTECTED]> wrote: > I was debugging a problem reported to me regarding PL/R, and found that > I can duplicate it using only R sources. It might be characterized as > possibly a misuse of the findFun() function, but I leave that for the R > devel experts to decide. > > The below results are all with R-2.5.1 (I can't seem to download > r-patched at the moment, but didn't see anything in the 2.5.1-patched > release notes indicating this issue had been noticed) on Fedora Core 6 > x86_64 (also duplicated with R-2.5.0 on FC7 i386). > > Steps to reproduce: > 8<------------------------ > configure, make, make install from source tree > cd tests/Embedding/ > make RNamedCall > ./RNamedCall #works as expected > mv foo.R foo.R.orig > ./RNamedCall #segfaults > 8<------------------------ > > output: > 8<------------------------ > Error in file(file, "r", encoding = encoding) : > unable to open connection > In addition: Warning message: > cannot open file 'foo.R', reason 'No such file or directory' in: > file(file, "r", encoding = encoding) > Error: could not find function "foo" > > *** caught segfault *** > address (nil), cause 'memory not mapped' > > Possible actions: > 1: abort (with core dump, if enabled) > 2: normal R exit > 3: exit R without saving workspace > 4: exit R saving workspace > Selection: 1 > aborting ... > Segmentation fault > 8<------------------------ > > The problem comes from RNamedCall starting at line 54: > 8<------------------------ > fun = findFun(install("foo"), R_GlobalEnv); > if(fun == R_NilValue) { > fprintf(stderr, "No definition for function foo. > Source foo.R and save the session.\n"); > UNPROTECT(1); > exit(1); > } > 8<------------------------ > > If foo.R was not found and never sourced, meaning that the object "foo" > does not exist, findFun never returns. Instead the segfault occurs at > line 719 in errors.c at the LONGJMP statement. Setting a breakpoint at > erros.c:719, the backtrace looks like this (will wrap poorly): > > 8<------------------------ > Breakpoint 2, jump_to_top_ex (traceback=TRUE, tryUserHandler=TRUE, > processWarnings=TRUE, resetConsole=TRUE, > ignoreRestartContexts=FALSE) at errors.c:719 > 719 LONGJMP(R_ToplevelContext->cjmpbuf, 0); > (gdb) bt > #0 jump_to_top_ex (traceback=TRUE, tryUserHandler=TRUE, > processWarnings=TRUE, resetConsole=TRUE, > ignoreRestartContexts=FALSE) at errors.c:719 > #1 0x00002aaaaab77e5d in verrorcall_dflt (call=0x609d78, > format=0x2aaaaace4a4d "%s", ap=0x7fffa13a94c0) > at errors.c:516 > #2 0x00002aaaaab7814a in Rf_errorcall (call=0x609d78, > format=0x2aaaaace4a4d "%s") at errors.c:551 > #3 0x00002aaaaab78347 in Rf_error (format=0x2aaaaace42da "could not > find function \"%s\"") at errors.c:578 > #4 0x00002aaaaab708e5 in Rf_findFun (symbol=0xc64f20, rho=0x649fa0) at > envir.c:1244 > #5 0x0000000000400e0c in bar1 () at RNamedCall.c:54 > #6 0x0000000000400d59 in main (argc=1, argv=0x7fffa13ab838) at > RNamedCall.c:16 > 8<------------------------ > > And then stepping into line 719 generates the segfault: > 8<------------------------ > (gdb) s > > Program received signal SIGSEGV, Segmentation fault. > 0x00002aaaaab701ce in Rf_findVar (symbol=0x6c12b8, rho=0x0) at envir.c:998 > 998 if (TYPEOF(rho) == NILSXP) > 8<------------------------ > > I believe this is happening because findFun() was not executed inside a > valid context, and therefore R_ToplevelContext->cjmpbuf is invalid. > > My question is -- is the above an abuse of findFun() by RNamedCall.c > (meaning I should avoid the same pattern)? Or maybe it should be wrapped > in something similar to R_ToplevelExec? > > ========================== > > On a related note, I found during my PL/R debugging that the segfault > was causing the same console based, interactive, "*** caught segfault > ***" logic to execute. I was able to confirm that R_Interactive was set > to TRUE in my PL/R session. > > It seems that Rf_initEmbeddedR() sets R_Interactive to TRUE and depends > on the output of isatty() to change it to FALSE in Rf_initialize_R() if > there is no tty. Unfortunately, the most common methods for starting > Postgres leave the tty attached (stdout and stderr are directed to the > log file). I ended up explicitly writing "R_Interactive = FALSE" just > after running Rf_initEmbeddedR() -- is this a safe and reasonable thing > to do? > > Thanks, > > Joe > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > -- Byron Ellis ([EMAIL PROTECTED]) "Oook" -- The Librarian ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel