diff options
| author | Miguel Sofer <miguel.sofer@gmail.com> | 2007-11-10 19:01:33 (GMT) | 
|---|---|---|
| committer | Miguel Sofer <miguel.sofer@gmail.com> | 2007-11-10 19:01:33 (GMT) | 
| commit | 1bb7bf057245c23fb001032ceb3df30a99b093ee (patch) | |
| tree | ee3e9b6761d7863d8db6a9e00353b6f533742f04 /unix/tclUnixInit.c | |
| parent | 9d4613e63ad9a84dc895ee578f5839138fc85dad (diff) | |
| download | tcl-1bb7bf057245c23fb001032ceb3df30a99b093ee.zip tcl-1bb7bf057245c23fb001032ceb3df30a99b093ee.tar.gz tcl-1bb7bf057245c23fb001032ceb3df30a99b093ee.tar.bz2 | |
	* generic/tclBasic.c:
	* generic/tclInt.h:
	* unix/tclUnixInit.c:
	* win/tclWin32Dll.c: restore simpler behaviour for stack checking,
	not adaptive to stack size changes after a thread is
	launched. Consensus is that "nobody does that", and so it is not
	worth the cost.
Diffstat (limited to 'unix/tclUnixInit.c')
| -rw-r--r-- | unix/tclUnixInit.c | 77 | 
1 files changed, 45 insertions, 32 deletions
| diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c index 4ae061c..86edc38 100644 --- a/unix/tclUnixInit.c +++ b/unix/tclUnixInit.c @@ -7,7 +7,7 @@   * Copyright (c) 1999 by Scriptics Corporation.   * All rights reserved.   * - * RCS: @(#) $Id: tclUnixInit.c,v 1.75 2007/11/10 16:08:10 msofer Exp $ + * RCS: @(#) $Id: tclUnixInit.c,v 1.76 2007/11/10 19:01:35 msofer Exp $   */  #include "tclInt.h" @@ -78,7 +78,6 @@  typedef struct ThreadSpecificData {      int *outerVarPtr;		/* The "outermost" stack frame pointer for  				 * this thread. */ -    int stackDetermineResult;	/* What happened when we did that? */      int *stackBound;            /* The current stack boundary */  } ThreadSpecificData;  static Tcl_ThreadDataKey dataKey; @@ -1028,21 +1027,21 @@ TclpFindVariable(  #ifndef TCL_NO_STACK_CHECK  int  TclpGetCStackParams( -    int ***stackBoundPtr) +    int **stackBoundPtr)  { -    int localVar; -    size_t stackSize;		/* The size of the current stack. */ +    int result = TCL_OK; +    size_t stackSize = 0;	/* The size of the current stack. */      ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);  				/* Most variables are actually in a  				 * thread-specific data block to minimise the  				 * impact on the stack. */ -	 +          if (stackGrowsDown == -1) {  	/*  	 * Not initialised!  	 */ -	stackGrowsDown = StackGrowsDown(&localVar); +	stackGrowsDown = StackGrowsDown(&result);      }      /* @@ -1051,37 +1050,47 @@ TclpGetCStackParams(       */      if (tsdPtr->outerVarPtr == NULL) { -	tsdPtr->outerVarPtr = &localVar; -	tsdPtr->stackDetermineResult = GetStackSize(&stackSize); +	tsdPtr->outerVarPtr = &result; +	result = GetStackSize(&stackSize); +	if (result != TCL_OK) { +	    /* Can't check, assume it always succeeds */ +	    stackGrowsDown = 1; +	    tsdPtr->stackBound = NULL; +	    goto done; +	}      } -    if ((stackGrowsDown && (&localVar < tsdPtr->stackBound)) -	    || (!stackGrowsDown && (&localVar > tsdPtr->stackBound))) { -	/* -	 * Stack failure - if we didn't already blow up, we are within the -	 * safety area. Recheck with the OS in case the stack was grown. -	 */ +    if (stackSize || (stackGrowsDown && (&result < tsdPtr->stackBound)) +		|| (!stackGrowsDown && (&result > tsdPtr->stackBound))) { +	    /* +	     * Either the thread's first pass or stack failure: set the params +	     */ -	tsdPtr->stackDetermineResult = GetStackSize(&stackSize); -    } +	if (!stackSize) { +	    /* +	     * Stack failure: if we didn't already blow up, we are within the +	     * safety area. Recheck with the OS in case the stack was grown.  +	     */ +	    result = GetStackSize(&stackSize); +	    if (result != TCL_OK) { +		/* Can't check, assume it always succeeds */ +		stackGrowsDown = 1; +		tsdPtr->stackBound = NULL; +		goto done; +	    } +	} -    if (tsdPtr->stackDetermineResult != TCL_OK) { -	switch (tsdPtr->stackDetermineResult) { -	    case TCL_BREAK: -		STACK_DEBUG(("skipping stack checks with failure\n")); -	    case TCL_CONTINUE: -		STACK_DEBUG(("skipping stack checks with success\n")); +	if (stackGrowsDown) { +	    tsdPtr->stackBound = (int *) ((char *)tsdPtr->outerVarPtr - +		    stackSize); +	} else { +	    tsdPtr->stackBound = (int *) ((char *)tsdPtr->outerVarPtr + +		    stackSize);  	} -	stackGrowsDown = 1; -	tsdPtr->stackBound = NULL; -    } else if (stackGrowsDown) { -	tsdPtr->stackBound = (int *) ((char *)tsdPtr->outerVarPtr - -		stackSize); -    } else { -	tsdPtr->stackBound = (int *) ((char *)tsdPtr->outerVarPtr + -		stackSize);      } -    *stackBoundPtr = &(tsdPtr->stackBound); + +    done: +    *stackBoundPtr = tsdPtr->stackBound;      return stackGrowsDown;  } @@ -1132,6 +1141,7 @@ GetStackSize(  	/*  	 * Some kind of confirmed error?!  	 */ +	STACK_DEBUG(("skipping stack checks with failure\n"));  	return TCL_BREAK;      }      if (rawStackSize > 0) { @@ -1149,12 +1159,14 @@ GetStackSize(  	/*  	 * getrlimit() failed, just fail the whole thing.  	 */ +	STACK_DEBUG(("skipping stack checks with failure: getrlimit failed\n"));  	return TCL_BREAK;      }      if (rLimit.rlim_cur == RLIM_INFINITY) {  	/*  	 * Limit is "infinite"; there is no stack limit.  	 */ +	STACK_DEBUG(("skipping stack checks with success: infinite limit\n"));  	return TCL_CONTINUE;      }      rawStackSize = rLimit.rlim_cur; @@ -1169,6 +1181,7 @@ GetStackSize(    finalSanityCheck:  #endif      if (rawStackSize <= 0) { +	STACK_DEBUG(("skipping stack checks with success\n"));  	return TCL_CONTINUE;      } | 
