[Rd] Child thread libR.so

Ryan C Metzger
Mon, 24 Aug 2015 14:18:10 -0000

I did some poking around with GDB and confirmed that the advice of
setting R_CStackLimit after init, which is echoed in the "threading
issues" section of the R-exts help document, isn't entirely useful
because init apparently loads the main package which trips over the
broken stack checking.

Stack trace:

#0  R_SignalCStackOverflow (usage=140732197147604) at errors.c:81
#1  0x00002aaaab0625b7 in Rf_eval (e=0x1b7592a8, rho=0x1b753960) at eval.c:545
#2  0x00002aaaab0871ca in R_ReplFile (fp=0x1b69a830, rho=0x1b753960)
at main.c:98
#3  0x00002aaaab087a27 in setup_Rmainloop () at main.c:861
#4  0x00002aaaab14a98b in Rf_initEmbeddedR (argc=<value optimized
out>, argv=<value optimized out>) at Rembedded.c:63

On Thu, Aug 20, 2015 at 1:21 PM, Ryan C Metzger <metzger.rc at gmail.com>
wrote:
> So I'm working on a custom front end to R, in one mode of the front
> end I dynamically load libR.so into a child worker thread. I'm very
> careful to make sure it is loaded by a single thread and loaded only
> once, but since it is a child thread it violates assumptions made by
> the stack size checking inside of R and I get innumerable errors along
> the lines of
>
> Error: C stack usage  140732526462740 is too close to the limit
>
> Digging through this email list (and I also found similar things out
> on google) I found the following advice from 2009
>
> ---------------------------------------- SNIP
>
------------------------------------------------------------------------------
>> Hi everyone!
>>   I meet one problem when embedding R in C code, when I run the the
>> R code in one child thread ,
>>   it always print error info:
>>    Error: C stack usage is too close to the limit
>>
>>   I also try to set R_CStackLimit = (uintptr_t)-1 to disable the C
>> stack check as the R-exts doc say,
>>   but it still does not work, the error info still exist.
>>
>
> That is the way to do it (and other project use it successfully) - the
> fact that it doesn't work means that you probably do it at the wrong
> place (you must set it *after* Rf_initialize_R).
>
> Cheers,
> Simon
> ---------------------------------------- SNIP
>
------------------------------------------------------------------------------
>
> my code is as follows
>
> ---------------------------------------- SNIP
>
------------------------------------------------------------------------------
> void init_r() {
>     SEXP aperm_function;
>
>     const char *init_argv[] = {"MyFront", "--vanilla",
"--slave"};
>     Rf_initEmbeddedR(sizeof (init_argv) / sizeof (init_argv[0]),
> (char**) init_argv);
>
>     R_CStackLimit = (uintptr_t)-1;
>
>     /*
>      * transposeVector above uses the R builtin function aperm instead of
>      * looking it up every time we need deal with transposing a
multidimensional
>      * intput/output look it up once here and save it off
>      */
>     aperm_function = findFun(install("aperm"), R_GlobalEnv);
>     if (aperm_function == NULL || aperm_function == R_NilValue ||
> aperm_function == R_UnboundValue) {
>         aperm_function = NULL;
>     } else {
>         aperm_expression = PROTECT(allocVector(LANGSXP, 2));
>
>         SETCAR(aperm_expression, aperm_function);
>     }
> }
> ---------------------------------------- SNIP
>
------------------------------------------------------------------------------
>
> but as I say I still get the error and it seems like the call to
> Rf_initEmbeddedR just never returns. As an experiment I edited
> config.h.in and removed the define for HAVE_GETRLIMIT and recompiled,
> thus compiling out the stack checking mechanism entirely. Then
> everything worked great!, so I know it's the stack checking mechanism
> from a child thread that is falling to pieces. So what I have in mind
> is looking to fix this mechanism so that it works from a child thread
> if the pthread library is available and submitting a patch. My
> question is two fold, 1. Is there a way to get this to work without a
> code change ( I'd like to be able to offer my front end stand alone
> and not have to bundle R with it ) 2. If I do come up with a diff, how
> do I go about submitting it back to the r foundation?
>
>
> for completeness the version of R I am using
>
>> version
>                _
> platform       x86_64-unknown-linux-gnu
> arch           x86_64
> os             linux-gnu
> system         x86_64, linux-gnu
> status
> major          3
> minor          2.1
> year           2015
> month          06
> day            18
> svn rev        68531
> language       R
> version.string R version 3.2.1 (2015-06-18)
> nickname       World-Famous Astronaut
>
> compiled from source with configure options
> head R-3.2.1/config.log
> This file contains any messages produced by compilers while
> running configure, to aid debugging if configure makes a mistake.
>
> It was created by R configure 3.2.1, which was
> generated by GNU Autoconf 2.69.  Invocation command line was
>
>   $ ./configure --prefix /u/rmetzger/linux_R_vanilla --enable-R-shlib
>
> ## --------- ##
> ## Platform. ##
>
> thank you!
> Ryan