-
-
Notifications
You must be signed in to change notification settings - Fork 31.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GH-91079: Implement C stack limits using addresses, not counters. #130007
base: main
Are you sure you want to change the base?
Conversation
…m independent constants
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This adds new public API, which needs documentation.
It also removes public API; that needs deprecation or SC exception.
When you're done making the requested changes, leave the comment: |
Love seeing this change! Thanks, Mark. |
The public API is
What API? |
Benchmarking shows a 0.0%-0.4% speedup on 64 bit platforms, and a 2% speedup on 32 bit windows, so it isn't slower. |
@encukou I've hidden the new function. I don't see any removals though, which API do you mean? |
Thanks for hiding it! There's also the newly added
I see these in
I don't think getting a SC exception should be a problem. |
We can add back |
It's C code, there is no such thing as private. |
Well, not documented, which just means people read the code to figure out what they mean. |
I really don't think we should be wasting our time on supporting incompetent C/C++ programmers who can't use APIs. |
I've just discovered |
@encukou |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
Do we really want to start prefixing every field with
_DONT_USE_THIS_
just in case?
No, an underscore is fine.
It's C, nothing is private at the language level, so we have a convention to mark the private/unstable stuff.
#ifdef USE_STACKCHECK | ||
if (PyOS_CheckStack()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you adjust the Py_EnterRecursiveCall
docs?
Python/ceval.c
Outdated
// test_descr crashed on sparc64 with >7000 but let's keep a margin of error. | ||
# define Py_C_STACK_SIZE 1600000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 7000 (and 8000 below) doesn't make much sense to me here.
|
||
#if defined(WIN32) && !defined(MS_WIN64) && !defined(_M_ARM) && defined(_MSC_VER) && _MSC_VER >= 1300 | ||
#if defined(WIN32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The definition of PyOS_CheckStack
still uses defined(_MSC_VER)
.
Looks like the #if
there (and the MSVC-specific includes) can be removed.
Could you remove the MSVC reference from the PyOS_CheckStack
docs?
@skip_emscripten_stack_overflow() | ||
def test_repr_deep(self): | ||
a = self.type2test([]) | ||
for i in range(get_c_recursion_limit() + 1): | ||
for i in range(100_000): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you comment on where the 100_000, and similar magic constants below, came from?
Perhaps it would be best to reuse the name exceeds_recursion_limit
, and set that to 100_000?
@@ -628,23 +628,34 @@ def test_mismatched_parens(self): | |||
r"does not match opening parenthesis '\('", | |||
["f'{a(4}'", | |||
]) | |||
self.assertRaises(SyntaxError, eval, "f'{" + "("*500 + "}'") | |||
self.assertRaises(SyntaxError, eval, "f'{" + "("*20 + "}'") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks worrying. Did the limit for nested parentheses go down over an order of magnitude?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. Previously, there was a counter and if it was exceeded a SyntaxError
was raised, but it could crash if the stack overflowed before the limit was reached.
Now we raise a SyntaxError
for unbalanced parens and a RecursionError
for a (potential) stack overflow.
See the new tests added below (line 656)
try: | ||
eval(txt) | ||
except SyntaxError: | ||
pass | ||
except MemoryError: | ||
pass | ||
except Exception as ex: | ||
self.fail(f"Should raise SyntaxError or MemoryError, not {type(ex)}") | ||
else: | ||
self.fail("No exception raised") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, you could use with self.assertRaises((SyntaxError, MemoryError)):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I don't know that was a thing. Thanks.
Python/pythonrun.c
Outdated
@@ -1538,24 +1538,21 @@ _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyComp | |||
/* | |||
* Return non-zero when we run out of memory on the stack; zero otherwise. | |||
*/ | |||
int | |||
PyOS_CheckStack(void) | |||
int PyOS_CheckStack(void) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: please revert the style change
int PyOS_CheckStack(void) | |
int | |
PyOS_CheckStack(void) |
Python/pythonrun.c
Outdated
} | ||
return 1; | ||
else { | ||
return -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be 1 as before? Nowadays -1 is usually used when an exception is set.
I have made the requested changes; please review again |
Thanks for making the requested changes! @iritkatriel, @encukou: please review the changes made to this pull request. |
Hopefully, this will also fix #113655.