Jupyter kernel crashes on an R's Error: attempt to use zero-length variable name

Issue #601 open
Michał Krassowski created an issue

Assigning a list with zero-length variable name is an error, but it is well-tolerated in R interactive sessions (the user gets Error: attempt to use zero-length variable name message and the session continues normally). However, the Jupyter kernel crashes in the interactive rpy2 use when this line is run:

%R list(''='zero-length variable name')

Following communicates are written out:

R[write to console]: Error: attempt to use zero-length variable name
R[write to console]: Execution halted

And a kernel crash pop-up follows: <Kernel Restarting> The kernel for notebook.ipynb appears to have died. It will restart automatically. A loosely-related issue was #409.

For me, this is only a minor nuisance, but it would be nice if - similarly to R interactive sessions - this error did not result in a crash of the kernel (as this can lead to a waste of minutes and sometimes hours of computations).

rpy2 3.2.2; JupyterLab 1.2.3; Python 3.7.5; R 3.6.1

Comments (10)

  1. Laurent Gautier

    The crash is odd, since I would expect the error raised by R to be just like any other runtime error occurring during the evaluation of R code (for which I have not seen issue reports in Jupyterlab so far).

  2. Laurent Gautier

    The issue is not specify to jupyter(lab). I can reproduce it from a Python terminal:

    >>> from rpy2 import robjects
    >>> robjects.r("list(''='zero-length variable name')")
    R[write to console]: Error: attempt to use zero-length variable name
    
    *** stack smashing detected ***: <unknown> terminated
    Aborted (core dumped)
    

  3. Laurent Gautier

    The error is actually happening during the parsing of the string as R code rather than during evaluation:

    In [1]: import rpy2.rinterface as ri                                                                                                                      
    
    In [2]: ri.initr()                                                                                                                                        
    Out[2]: 0
    
    In [3]: e = ri.parse("'a' + 2")                                                                                                                           
    
    In [4]: e                                                                                                                                                 
    Out[4]: <rpy2.rinterface.ExprSexpVector object at 0x7fb152ca9dc8> [RTYPES.EXPRSXP]
    
    In [5]: e = ri.parse("list()")                                                                                                                            
    
    In [6]: e = ri.parse("list('')")                                                                                                                          
    
    In [7]: e = ri.parse("list(''=1)")                                                                                                                        
    R[write to console]: Error: attempt to use zero-length variable name
    
    R[write to console]: Fatal error: unable to initialize the JIT
    
    
    *** stack smashing detected ***: <unknown> terminated
    Aborted (core dumped)
    

  4. Laurent Gautier

    This seems to be be a weird behavior, or a bug, originating from R’s C API. The following incomplete parsing is raising a parsing error (as it should):

    >>> import rpy2.rinterface as ri
    >>> ri.initr()
    >>> e = ri.parse("list(''=1+") 
    ---------------------------------------------------------------------------
    RParsingError                             Traceback (most recent call last)
    ...
    

    However, changing slightly where the parsing error originates from, leads to the segfault:

    >>> e = ri.parse("list(''=123") 
    R[write to console]: Error: attempt to use zero-length variable name
    
    R[write to console]: Fatal error: unable to initialize the JIT
    
    
    *** stack smashing detected ***: <unknown> terminated
    

  5. Laurent Gautier

    I found the following in src/main/gram.c(R source):

    /* Memory leak
    
       yyparse(), as generated by bison, allocates extra space for the parser
       stack using malloc(). Unfortunately this means that there is a memory
       leak in case of an R error (long-jump). In principle, we could define
       yyoverflow() to relocate the parser stacks for bison and allocate say on
       the R heap, but yyoverflow() is undocumented and somewhat complicated
       (we would have to replicate some macros from the generated parser here).
       The same problem exists at least in the Rd and LaTeX parsers in tools.
    */
    

  6. Michał Krassowski reporter

    I admire your work on rpy2, tracking this down to a memory leak in R must have been interesting.

    I got another syntax error which leads to:

    R[write to console]: Fatal error: unable to initialize the JIT
    R[write to console]: Execution halted
    

    And this is, again, a slight annoyance.

    User story: in R one can convert latex to plotmath using latex2exp package. However, we need to escape the backslash character to prevent it from being interpreted as a special character sequence (like a new line or caret return). Failing to escape will lead to an error, but again should not break the interactive session. But it does (kernel dies).

    An example:

    >>> TeX(paste0("Pearson's Chi-squared test: \chi^2=", chisq$statistic))
    R[write to console]: Error: '\c' is an unrecognized escape in character string starting ""Pearson's Chi-squared test: \c"
    R[write to console]: Fatal error: unable to initialize the JIT
    R[write to console]: Execution halted
    

    Again, this can be frustrating to lose data, especially if someone instinctively writes “normal” (unescaped) latex.

    Expected behaviour: I get an error message, fix the typo and carry on.

    All the versions remain unchanged (as in my first post).

    Edit: please, let me know if you would like this in a new issue, I can fill in the new issue form - just though that his may have a common origin.

  7. Log in to comment