From jeff.horner at vanderbilt.edu  Sat Nov  6 16:35:30 2004
From: jeff.horner at vanderbilt.edu (Jeffrey Horner)
Date: Sat Nov  6 16:35:50 2004
Subject: [Rd] is.vector() gives error (PR#7288)
In-Reply-To: <x21xg19raa.fsf@biostat.ku.dk>
References: <20041014162543.92EC710452@slim.kubism.ku.dk>
	<x21xg19raa.fsf@biostat.ku.dk>
Message-ID: <418CEF42.70003@vanderbilt.edu>

Peter Dalgaard wrote:
[...]
> The other possibility is that you're tickling a low-level, system
> dependent bug in the evaluator. Can anyone reproduce this?
> 

I'm running up against this when embedding libR.so into apache2. 
Whenever I call Rf_initEmbeddedR(), I get the following message:

Error in lazyLoadDBfetch(key, datafile, compressed, envhook) :
         recursive default argument reference a

and then apache2 segfaults when it tries to run R_tryEval(). It happens 
with R-2.0.0 and R-patched_2004-11-05, but not with R-1.9.1.

Here's the code that I'm running in apache2:
-------------
/* initialization code for apache process */
static void mod_R_register_hooks (apr_pool_t *p)
{
     char *argv[] = {"mod_R", "--gui=none", "--slave", "--silent", 
"--vanilla","--no-readline"};
     int argc = sizeof(argv)/sizeof(argv[0]);

     ap_hook_handler(mod_R_method_handler, NULL, NULL, APR_HOOK_MIDDLE);

     Rf_initEmbeddedR(argc, argv);

     R_Outputfile = NULL;       /* stdout */
     /* R_Consolefile = NULL; */ /* stderr */

     ptr_R_WriteConsole = Rscript_WriteConsole; /* stdout goes to browser */

}
-----------------------
And then for every http request...
-----------------------
static SEXP R_source_fun;
static SEXP R_source_arg;

static int mod_R_method_handler (request_rec *r)
{

     SEXP val, expr;
     int errorOccurred;

     // Only handle if correct handler
     if (strcmp(r->handler,"application/x-httpd-r")){
         return DECLINED;
     }

     // Setup CGI
     ap_add_common_vars(r);
     ap_add_cgi_vars(r);

     ap_set_content_type(r,"text/html");
     rapache_current_req = r;

     /* Call source(r->filename) */
     /* Setup source() function call */

     /* function */
     R_source_fun = Rf_findFun(Rf_install("source"), R_GlobalEnv);
     PROTECT(R_source_fun);

     /* argument */
     PROTECT(R_source_arg = NEW_CHARACTER(1));
     SET_STRING_ELT(R_source_arg, 0, COPY_TO_USER_STRING(r->filename));

     /* expression */
     PROTECT(expr = allocVector(LANGSXP,2));
     SETCAR(expr,R_source_fun);
     SETCAR(CDR(expr),R_source_arg);

     errorOccurred=1;
     val = R_tryEval(expr,NULL,&errorOccurred);
     if (errorOccurred){

         // Send a message to stderr (apache redirects this to the error 
log)
         fprintf(stderr,"apache2_mod_R: source(%s) failed: 
%x!\n",r->filename,val);
     }
     UNPROTECT(3);

     return OK;
}

The above code works fine with R-2.0.0, R-patched_2004-11-05, and 
R-1.9.1 when I run it as a standalone command-line app in the following 
code and link against appropriate libR.so:

--------------------
int main(int ac, char **av){
     FILE *fd;
     ParseStatus status;
     SEXP expr, R_source_fun, R_source_arg, val;
     Rboolean ok;
     int errorOccurred;

     char *argv[] = {"mod_R", "--gui=none", "--slave", "--silent", 
"--vanilla","--no-readline"};
     int argc = sizeof(argv)/sizeof(argv[0]);

     if (ac != 2){
         printf("Usage: %s filename\n",av[0]);
         exit(1);
     }

     Rf_initEmbeddedR(argc, argv);

     /* function */
     R_source_fun = Rf_findFun(Rf_install("source"), R_GlobalEnv);
     PROTECT(R_source_fun);

     /* argument */
     PROTECT(R_source_arg = NEW_CHARACTER(1));
     SET_STRING_ELT(R_source_arg, 0, COPY_TO_USER_STRING(av[1]));

     /* expression */
     PROTECT(expr = allocVector(LANGSXP,2));
     SETCAR(expr,R_source_fun);
     SETCAR(CDR(expr),R_source_arg);

     errorOccurred=1;
     val = R_tryEval(expr,NULL,&errorOccurred);
     if (errorOccurred){

         // Send a message to stderr (apache redirects this to the error 
log)
         fprintf(stderr,"source(%s) failed: %x!\n",av[1],val);
         //fprintf(stderr,"apache2_mod_R: handler is %s\n",r->handler);
         //fprintf(stderr,"apache2_mod_R: filename is %s\n",r->filename);
     }
     UNPROTECT(3);

}
----------------------

When I run apache2 inside gdb until it segfaults:
----------------------
$ gdb apache2/bin/httpd
GNU gdb 6.1-debian
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain 
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-linux"...Using host libthread_db 
library "/lib/libthread_db.so.1".

(gdb) run -X
Starting program: /home/hornerjr/R_MODULE/apache2/bin/httpd -X
[Thread debugging using libthread_db enabled]
[New Thread 16384 (LWP 15333)]
Detaching after fork from child process 15336.
httpd: Could not determine the server's fully qualified domain name, 
using 160.129.129.111 for ServerName

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 16384 (LWP 15333)]
0x403dc607 in Rf_applyClosure (call=0x83eab20, op=0x8ef8b74, 
arglist=0x8ea8168, rho=0x8ef8ca8, suppliedenv=0x8a9b814) at eval.c:561
warning: Source file is more recent than executable.

561             if (R_ReturnedValue == R_RestartToken) {
(gdb) where
#0  0x403dc607 in Rf_applyClosure (call=0x83eab20, op=0x8ef8b74, 
arglist=0x8ea8168, rho=0x8ef8ca8, suppliedenv=0x8a9b814) at eval.c:561
#1  0x08ef8b74 in ?? ()
#2  0x083eab20 in ?? ()
#3  0x08ef8b74 in ?? ()
#4  0x08ea8168 in ?? ()
#5  0x08ef8ca8 in ?? ()
#6  0x08a9b814 in ?? ()
#7  0x40403ea1 in Rf_protect (s=0x86aa094) at memory.c:2068
Previous frame inner to this frame (corrupt stack?)
------------------------------

I'm not exactly sure if it's a threading issue (I compiled apache2 
--without-threads), and httpd -X runs exactly one process, but I'll post 
as soon as I have more information...


-- 
Jeffrey Horner       Computer Systems Analyst         School of Medicine
615-322-8606         Department of Biostatistics   Vanderbilt University


[Rd] is.vector() gives error (PR#7288)
Jeffrey Horner