summaryrefslogtreecommitdiffstats
path: root/unix
diff options
context:
space:
mode:
Diffstat (limited to 'unix')
-rw-r--r--unix/tclUnixInit.c77
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;
}