Re: [Rd] sending signals to embedded R

From: <deepayan.sarkar_at_gmail.com>
Date: Sun, 06 May 2007 19:57:04 -0500

On 5/6/07, Jeffrey Horner <jeff.horner_at_vanderbilt.edu> wrote:
> Luke Tierney wrote:

[...]

> >> Is there a reason R_ProcessEvents cannot be set on Unix but can on
> >> Mac? It doesn't seem user-settable on Windows, but whatever the built
> >> in default is seems to handle the Qt event loop. And for that matter,
> >> why is it possible to set the file.edit callback on Mac but not Linux?
> >> This seems arbitrary, and no explanation is given (that I could find).
> >
> > The R_PRocessEvents callback may be settable on MacOS but I'm not sure
> > it's used -- at least a quick grep didn't reveal its use anywhere
> > outside the gnuwin32 code.

I meant the callback ptr_R_ProcessEvents (in Rinterface.h). The Mac GUI source has (this is probably not the latest version):

dsarkar_at_kanika:~/Mac-GUI-1.17$ grep -i ptr_r_process */* REngine/Rinit.c:extern void (*ptr_R_ProcessEvents)(); REngine/Rinit.c: ptr_R_ProcessEvents = Re_ProcessEvents;

and R/trunk/src/unix/aqua.c has:

void R_ProcessEvents(void)
{

    if(!useaqua){

        if (R_interrupts_pending)
            onintr();
        return;
    } else
        ptr_R_ProcessEvents();

}

> > It would be good to unify the Mac and *nix mechanisms here since the
> > OS underpinings are now so similar, but it will have to get high
> > enough on someone's priority list to happen.

[...]

> >> The problem I'm having with this solution is that whenever I interrupt
> >> a graphics command, R crashes. This is true for commands being
> >> evaluated by R_tryEval, but not those run from the REPL (for example,
> >> if I make the call inside a debug() environment, interrupting it
> >> causes no problems). As far as I can tell, this is only a problem with
> >> graphics; other commands can be interrupted even when run using
> >> R_tryEval().
> >
> > That sounds like a longjmp being done to a place that doesn't exist --
> > maybe a threading issue in Qt. See what gdb tells you about where the
> > crash is occurring. It might be different for onintr and kill. You
> > might also try just setting the R_interrupts_pending flag from the
> > interrupt event handler rather than calling onintr (which probably
> > longjmp's) or kill (which may be doing something you don't want if
> > other threads with other signal handlers are involved).

I will have to start learning about gdb sometime soon, but in this case, the problem seems to be due to the interaction of R_tryEval() and graphics, and has nothing to do with interruptions. Here's a variant of the trEval test case that triggers a legitimate error caused by

grid.text('foo', gp = gpar(font=1, fontface=1))

dsarkar_at_kanika:~$ cat tryEvalGraphics.c ## beware of line wrapping

/*

   Compile this as:

RPROG=R-devel

export LD_LIBRARY_PATH=`${RPROG} RHOME`/lib:\${LD_LIBRARY_PATH} gcc `${RPROG} CMD config --cppflags` \

    `${RPROG} CMD config --ldflags` \
    -o tryEvalGraphics tryEvalGraphics.c

 */

#include <Rinternals.h>
#include <Rembedded.h>

#include <R_ext/Parse.h>

int
main(int argc, char *argv[])
{

    SEXP e, val;
    int i, errorOccurred;
    ParseStatus status;
    char *cmds[] = {

        "library(lattice)",
        "library(grid)",
        "grid.text('foo', gp = gpar(font=1, fontface=1))",
        "xyplot(1 ~ 1, panel = function() grid.text('foo', gp =
gpar(font=1, fontface=1)))"

    };

    argv[0] = "R";
    Rf_initEmbeddedR(argc, argv);

    for (i = 0; i < 4; i++) {

        printf("** I **: Executing command: %s\n", cmds[i]);
        fflush(stdout); sleep(1);
        PROTECT(e = R_ParseVector(mkString(cmds[i]), -1, &status, R_NilValue));
        val = R_tryEval(VECTOR_ELT(e, 0), NULL, &errorOccurred);
        if (errorOccurred) { Rprintf("Error executing: %s\n", cmds[i]); }
        else Rf_PrintValue(val);
        UNPROTECT(1);
        printf("** I **: Succeeded\n");
        fflush(stdout); sleep(1);

    }

    Rf_endEmbeddedR(0);
    return(0);
}

Running this, I get:

dsarkar_at_kanika:~$ R-devel CMD ./tryEvalGraphics

R version 2.6.0 Under development (unstable) (2007-05-04 r41439)

[...]

[Previously saved workspace restored]

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: 3
dsarkar_at_kanika:~$

Note that the first error (which doesn't actually get around to starting a device) is handled properly, while the second is not.

[...]

> Deepayan, this is your code from quter-20070502 below, where R_tryEval
> is called:

>

> PROTECT(cmdSexp = mkString(cmd));
> PROTECT(cmdExpr = R_ParseVector(cmdSexp, -1, &status, R_NilValue));
> if (status == PARSE_OK) {
> int i, errorOccurred;
> for(i = 0; i < length(cmdExpr); i++) {
> ans = R_tryEval(VECTOR_ELT(cmdExpr, i),
> NULL, &errorOccurred);
> }
> if (errorOccurred) ans = R_NilValue;
> UNPROTECT(2);
>

> Question: is each element of cmdExpr actually on the protection stack?
> Or rather, is the caller guaranteed that the cmdExpr element will not be
> garbage collected? My assumption is yes, since cmdExpr is, but I could
> be wrong.

Normally I would say yes, because my understanding is that sub-elements of protected SEXP's are supposed to be automatically protected. But I don't really know what happens when there is an error. On the other hand, I haven't been seeing any errors (other than the graphics one described above) recently with that code.

One possibly relevant factoid: a few days ago I was trying to play with R_topLevelExec(), and that seemed to require an extra UNPROTECT() for no reason (there's a similar hack in rkward). I sort of got it working, but two consecutive errors reproducibly took me to a situation where the same error message would get repeated whatever I did after that. I didn't pursue this because I figured out an alternative solution to my problem.

-Deepayan

> Just curious because I just ran into troubles with calling
> R_tryEval with unprotected expressions and accepting signals. I
> witnessed what Luke explained above, that longjmp's were being done to a
> place that I wasn't anticipating, e.g. R_tryEval was never returning.
>
> Jeff



R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Mon 07 May 2007 - 00:59:37 GMT

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 Tue 08 May 2007 - 05:33:58 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.