Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R extensions in C: Consult SEXP PROTECT Stack Height

Tags:

c

r

I'm writing R extensions using the .Call interface, and I'm trying to track down a stack imbalance warning. I would find it very helpful if I were able to consult the stack height at various points in the code to isolate internal C functions that are not returning at the same SEXP PROTECT stack height they were called with.

Is there a way to do this?

And yes, I realize that I wouldn't have to worry about any of this if I used Rcpp, but I'm in too deep here to change.

One less than ideal possibility is a pattern like:

int start, end;
PROTECT_WITH_INDEX(R_NilValue, &start);
UNPROTECT(1);
call_to_suspect_fun();
PROTECT_WITH_INDEX(R_NilValue, &end);
UNPROTECT(1);
if(start != end) error("Stack imbalance right here!");

which seems super awkward. I guess it's easy enough to turn into a function, but I would be surprised if there isn't a better built in option.

like image 431
BrodieG Avatar asked Dec 22 '15 20:12

BrodieG


1 Answers

The top of the stack is not part of the public API but can be made visible

#include "Rinternals.h"

extern int R_PPStackTop;

SEXP stacktop()
{
    SEXP x;
    Rprintf("%d\n", R_PPStackTop);
    x = PROTECT(allocVector(INTSXP, 1));
    Rprintf("%d\n", R_PPStackTop);
    UNPROTECT(1);
    Rprintf("%d\n", R_PPStackTop);
    return Rf_ScalarInteger(R_PPStackTop);
}

Leading to

$ R CMD SHLIB stacktop.c 2&> /dev/null
$ R --vanilla -e "dyn.load('stacktop.so'); .Call('stacktop')"
> dyn.load('stacktop.so'); .Call('stacktop')
3
4
3
[1] 3
like image 59
Martin Morgan Avatar answered Nov 13 '22 20:11

Martin Morgan