[rkward-cvs] SF.net SVN: rkward: [2157] branches/release_branch_0.4.8

tfry at users.sourceforge.net tfry at users.sourceforge.net
Fri Nov 2 11:48:02 UTC 2007


Revision: 2157
          http://rkward.svn.sourceforge.net/rkward/?rev=2157&view=rev
Author:   tfry
Date:     2007-11-02 04:48:01 -0700 (Fri, 02 Nov 2007)

Log Message:
-----------
Merge the stack limit detection patches from trunk (revs. 2152, and 2156)

Modified Paths:
--------------
    branches/release_branch_0.4.8/ChangeLog
    branches/release_branch_0.4.8/rkward/rbackend/rembedinternal.cpp
    branches/release_branch_0.4.8/rkward/rbackend/rembedinternal.h
    branches/release_branch_0.4.8/rkward/rbackend/rkpthreadsupport.cpp
    branches/release_branch_0.4.8/rkward/rbackend/rkpthreadsupport.h
    branches/release_branch_0.4.8/rkward/rbackend/rthread.cpp

Modified: branches/release_branch_0.4.8/ChangeLog
===================================================================
--- branches/release_branch_0.4.8/ChangeLog	2007-11-02 11:42:47 UTC (rev 2156)
+++ branches/release_branch_0.4.8/ChangeLog	2007-11-02 11:48:01 UTC (rev 2157)
@@ -1,3 +1,4 @@
+- More reliable C stack limit detection on some systems
 - Fixed: Console accepted pasted input while a command is running
 - Fixed: Analysis->Moments->Moment plugin did not use the order-parameter
 - Fixed: Crash on simple assignments in globalenv() with R < 2.4.0

Modified: branches/release_branch_0.4.8/rkward/rbackend/rembedinternal.cpp
===================================================================
--- branches/release_branch_0.4.8/rkward/rbackend/rembedinternal.cpp	2007-11-02 11:42:47 UTC (rev 2156)
+++ branches/release_branch_0.4.8/rkward/rbackend/rembedinternal.cpp	2007-11-02 11:48:01 UTC (rev 2157)
@@ -31,6 +31,7 @@
 #undef FALSE
 
 #include "rklocalesupport.h"
+#include "rkpthreadsupport.h"
 
 extern "C" {
 #define R_INTERFACE_PTRS 1
@@ -624,30 +625,58 @@
 	return R_NilValue;
 }
 
-bool REmbedInternal::startR (int argc, char** argv, size_t stacksize, void *stackstart) {
+#ifdef R_2_3
+void R_CheckStackWrapper (void *) {
+	R_CheckStack ();
+}
+#endif
+
+bool REmbedInternal::startR (int argc, char** argv, bool stack_check) {
 	RK_TRACE (RBACKEND);
 
 	r_running = true;
+	bool ok = true;
 #ifdef R_2_3
 	Rf_initialize_R (argc, argv);
-	R_CStackStart = (uintptr_t) stackstart;
-	R_CStackLimit = stacksize;
+
+	if (stack_check) {
+		char dummy;
+		size_t stacksize;
+		void *stackstart;
+		RKGetCurrentThreadStackLimits (&stacksize, &stackstart, &dummy);
+		R_CStackStart = (uintptr_t) stackstart;
+		R_CStackLimit = stacksize;
+	} else {
+		R_CStackStart = (uintptr_t) -1;
+		R_CStackLimit = (uintptr_t) -1;
+	}
+
 	setup_Rmainloop ();
-	RKGlobals::na_double = NA_REAL;
+
+	if (stack_check) {
+		// safety check: If we are beyond the stack boundaries already, we better disable stack checking
+		// this has to come *after* the first setup_Rmainloop ()!
+		Rboolean stack_ok = R_ToplevelExec (R_CheckStackWrapper, (void *) 0);
+		if (!stack_ok) {
+			RK_DO (qDebug ("R_CheckStack() failed during initialization. Will disable stack checking and try to re-initialize."), RBACKEND, DL_WARNING);
+			RK_DO (qDebug ("If this does not work, try the --disable-stack-check command line option, *and* submit a bug report."), RBACKEND, DL_WARNING);
+			R_CStackStart = (uintptr_t) -1;
+			R_CStackLimit = (uintptr_t) -1;
+			setup_Rmainloop ();
+		}
+	}
+
 	R_Interactive = (Rboolean) TRUE;
-	R_ReplDLLinit ();
-	RKWard_RData_Tag = Rf_install ("RKWard_RData_Tag");
-	return true;
 #else
-	bool ok = (Rf_initEmbeddedR (argc, argv) >= 0);
+	ok = (Rf_initEmbeddedR (argc, argv) >= 0);
+#endif
 	RKGlobals::na_double = NA_REAL;
 	R_ReplDLLinit ();
 	RKWard_RData_Tag = Rf_install ("RKWard_RData_Tag");
-#	ifdef R_2_6
+#ifdef R_2_6
 	R_LastvalueSymbol = Rf_install (".Last.value");
-#	endif
+#endif
 	return ok;
-#endif
 }
 
 SEXP doUpdateLocale () {

Modified: branches/release_branch_0.4.8/rkward/rbackend/rembedinternal.h
===================================================================
--- branches/release_branch_0.4.8/rkward/rbackend/rembedinternal.h	2007-11-02 11:42:47 UTC (rev 2156)
+++ branches/release_branch_0.4.8/rkward/rbackend/rembedinternal.h	2007-11-02 11:48:01 UTC (rev 2157)
@@ -87,9 +87,8 @@
 /** low-level initialization of R
 @param argc Number of arguments as would be passed on the commandline to R
 @param argv Arguments as would be passed on the commandline to R
- at param stacksize Stacksize to use in the R thread
- at param stackstart Base of stack to use in the R thread */
-	bool startR (int argc, char **argv, size_t stacksize, void *stackstart);
+ at param stack_check C stack checking enabled */
+	bool startR (int argc, char **argv, bool stack_check);
 /** low-level running of a command.
 @param command command to be run
 @param error this will be set to a value in RKWardError depending on success/failure of the command

Modified: branches/release_branch_0.4.8/rkward/rbackend/rkpthreadsupport.cpp
===================================================================
--- branches/release_branch_0.4.8/rkward/rbackend/rkpthreadsupport.cpp	2007-11-02 11:42:47 UTC (rev 2156)
+++ branches/release_branch_0.4.8/rkward/rbackend/rkpthreadsupport.cpp	2007-11-02 11:48:01 UTC (rev 2157)
@@ -29,8 +29,7 @@
 
 /* Much of this code is borrowed from WINE (http://www.winehq.org) */
 
-void RKGetCurrentThreadStackLimits (size_t *size, void **base) {
-	char dummy;
+void RKGetCurrentThreadStackLimits (size_t *size, void **base, char *reference) {
 	int direction;
 #ifdef HAVE_PTHREAD_GETATTR_NP
 	pthread_attr_t attr;
@@ -49,18 +48,18 @@
 #else
 #	warning Cannot determine the stack limits of a pthread on this system
 #	warning R C stack checking will be disabled
-	*base = &dummy;
+	*base = reference;
 	*size = (unsigned long) -1;
 	return;
 #endif
 	// in which direction does the stack grow?
 	{
 		char dummy2;
-		direction = (&dummy) > (&dummy2) ? 1 : -1;
+		direction = reference > (&dummy2) ? 1 : -1;
 	}
 
 	// in which direction does the stack base lie?
-	int base_direction = (*base) > (&dummy) ? 1 : -1;
+	int base_direction = (*base) > reference ? 1 : -1;
 
 	// switch base / top, if necessary
 	if (base_direction != direction) {
@@ -68,7 +67,7 @@
 	}
 
 	// sanity check, as on some systems the stack direction is mis-detected somehow.
-	long usage = direction * ((unsigned long) (*base) - (unsigned long) (&dummy));
+	long usage = direction * ((unsigned long) (*base) - (unsigned long) (reference));
 	if ((usage < 0) || (unsigned long) usage > (unsigned long) (*size)) {
 		RK_DO (qDebug ("Stack boundaries detection produced bad results. Disabling stack checking."), RBACKEND, DL_WARNING);
 		*size = (unsigned long) -1;

Modified: branches/release_branch_0.4.8/rkward/rbackend/rkpthreadsupport.h
===================================================================
--- branches/release_branch_0.4.8/rkward/rbackend/rkpthreadsupport.h	2007-11-02 11:42:47 UTC (rev 2156)
+++ branches/release_branch_0.4.8/rkward/rbackend/rkpthreadsupport.h	2007-11-02 11:48:01 UTC (rev 2157)
@@ -21,6 +21,6 @@
 #include <stddef.h>
 
 /** Try different ways to get the stack limits of the currently running thread */
-void RKGetCurrentThreadStackLimits (size_t *size, void **base);
+void RKGetCurrentThreadStackLimits (size_t *size, void **base, char *reference);
 
 #endif

Modified: branches/release_branch_0.4.8/rkward/rbackend/rthread.cpp
===================================================================
--- branches/release_branch_0.4.8/rkward/rbackend/rthread.cpp	2007-11-02 11:42:47 UTC (rev 2156)
+++ branches/release_branch_0.4.8/rkward/rbackend/rthread.cpp	2007-11-02 11:48:01 UTC (rev 2157)
@@ -18,7 +18,6 @@
 
 #include "rinterface.h"
 #include "rcommandstack.h"
-#include "rkpthreadsupport.h"
 #include "../settings/rksettingsmoduler.h"
 #include "../settings/rksettingsmodulegeneral.h"
 #include "../rkglobals.h"
@@ -466,15 +465,7 @@
 	RKWardStartupOptions *options = RKWardMainWindow::getStartupOptions ();
 	RK_ASSERT (options);
 
-	size_t stacksize;
-	void *stackstart;
-	if (options->no_stack_check) {
-		stacksize = (unsigned long) -1;
-		stackstart = (void *) -1;
-	} else {
-		RKGetCurrentThreadStackLimits (&stacksize, &stackstart);
-	}
-	startR (argc, argv, stacksize, stackstart);
+	startR (argc, argv, !(options->no_stack_check));
 
 	connectCallbacks ();
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the rkward-tracker mailing list