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 | |
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')
-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; } |