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
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
Ryan, if you read the piece you quoted from more carefully, you'll notice it says "Rf_initialize_R" - which is quite critical in this matter. Cheers, Simon On Aug 24, 2015, at 9:18 AM, Ryan C Metzger <metzger.rc at gmail.com> wrote:> 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 > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >