[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--