[Patches] Re: [Patch #101238] PyOS_CheckStack for Windows (MSVC)

Fredrik Lundh Fredrik Lundh" <effbot@telia.com
Tue, 22 Aug 2000 09:41:45 +0200


This is a multi-part message in MIME format.

------=_NextPart_000_007E_01C00C1D.2FA1ED60
Content-Type: text/plain;
	charset="ibm850"
Content-Transfer-Encoding: 7bit

(cannot login to SF right now, so I'll follow up by mail instead)

guido:
> This looks fine to me -- but when I test it (VC 6 on Win98), it doesn't
> work.  Try this:
> 
> class C:
>   def __getattr__(self, a): return self.x
> 
> C()
> 
> This still aborts the program.

note that I've just implemented the CheckStack operation for
MSVC; I didn't plug more holes in the interpreter.  see the
attached patch for an attempt to fix this one.

(it seems to work, but the getattr code is a bit convoluted, so
it's possible that the stack check should really be placed some-
where else...)

> As shown it breaks the build for _sre because the declaration for
> PyOS_CheckStack() doesn't use DL_IMPORT().  (MSVC 6.0 on Win98.)

well, I just rebuilt the core interpreter, and tested the __str__
and __repr__ cases (Bug #110615).  this glitch is fixed in the
new patch.

:::

CheckStack is also used to prevent run-away recursion in main
interpreter, but the recursion limit check catches that before you
run out of stack on Windows (with a standard stack, that is).

maybe the recursion limit check should be disabled if CheckStack
is available?

:::

I've attached a new version of the patch.  I'll post it to SF later
today.

</F>

------=_NextPart_000_007E_01C00C1D.2FA1ED60
Content-Type: text/plain;
	name="stack-patch.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="stack-patch.txt"

Index: Include/pythonrun.h
===================================================================
RCS file: /cvsroot/python/python/dist/src/Include/pythonrun.h,v
retrieving revision 2.32
diff -c -r2.32 pythonrun.h
*** Include/pythonrun.h	2000/08/07 21:00:42	2.32
--- Include/pythonrun.h	2000/08/22 07:13:15
***************
*** 87,94 ****
  DL_IMPORT(char *) PyOS_Readline(char *);
  extern DL_IMPORT(int) (*PyOS_InputHook)(void);
  extern DL_IMPORT(char) *(*PyOS_ReadlineFunctionPointer)(char *);
  #ifdef USE_STACKCHECK
! int PyOS_CheckStack(void);		/* Check that we aren't overflowing our stack */
  #endif
  
  #ifdef __cplusplus
--- 87,106 ----
  DL_IMPORT(char *) PyOS_Readline(char *);
  extern DL_IMPORT(int) (*PyOS_InputHook)(void);
  extern DL_IMPORT(char) *(*PyOS_ReadlineFunctionPointer)(char *);
+ 
+ /* Stack size, in "pointers" (so we get extra safety margins
+    on 64-bit platforms).  On a 32-bit platform, this translates
+    to a 2000-byte margin. */
+ #define PYOS_STACK_THRESHOLD 500
+ 
+ #if defined(WIN32) && defined(_MSC_VER)
+ /* Enable stack checking under Microsoft C */
+ #define USE_STACKCHECK
+ #endif
+ 
  #ifdef USE_STACKCHECK
! /* Check that we aren't overflowing our stack */
! DL_IMPORT(int) PyOS_CheckStack(void);
  #endif
  
  #ifdef __cplusplus
Index: Python/pythonrun.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v
retrieving revision 2.107
diff -c -r2.107 pythonrun.c
*** Python/pythonrun.c	2000/08/15 16:13:37	2.107
--- Python/pythonrun.c	2000/08/22 07:13:18
***************
*** 1165,1167 ****
--- 1165,1196 ----
  	       (strcmp(filename, "<stdin>") == 0) ||
  	       (strcmp(filename, "???") == 0);
  }
+ 
+ 
+ #if defined(USE_STACKCHECK) 
+ #if defined(WIN32) && defined(_MSC_VER)
+ 
+ /* Stack checking for Microsoft C */
+ 
+ #include <malloc.h>
+ #include <excpt.h>
+ 
+ int
+ PyOS_CheckStack()
+ {
+ 	__try {
+ 		/* _alloca throws a stack overflow exception if there's
+ 		   not enough space left on the stack */
+ 		_alloca(PYOS_STACK_THRESHOLD * sizeof(void*));
+ 		return 0;
+ 	} __except (EXCEPTION_EXECUTE_HANDLER) {
+ 		/* just ignore all errors */
+ 	}
+ 	return 1;
+ }
+ 
+ #endif /* WIN32 && _MSC_VER */
+ 
+ /* Alternate implementations can be added here... */
+ 
+ #endif /* USE_STACKCHECK */
Index: Objects/classobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v
retrieving revision 2.104
diff -c -r2.104 classobject.c
*** Objects/classobject.c	2000/08/18 04:57:32	2.104
--- Objects/classobject.c	2000/08/22 07:13:21
***************
*** 639,644 ****
--- 639,650 ----
  	res = instance_getattr1(inst, name);
  	if (res == NULL && (func = inst->in_class->cl_getattr) != NULL) {
  		PyObject *args;
+ #ifdef USE_STACKCHECK
+ 		if (PyOS_CheckStack()) {
+ 			PyErr_SetString(PyExc_MemoryError, "Stack overflow");
+ 			return NULL;
+ 		}
+ #endif
  		PyErr_Clear();
  		args = Py_BuildValue("(OO)", inst, name);
  		if (args == NULL)

------=_NextPart_000_007E_01C00C1D.2FA1ED60--