Comparisons and sorting of a numeric class....

Chris Angelico rosuav at gmail.com
Tue Jan 13 12:20:06 CET 2015


On Tue, Jan 13, 2015 at 10:00 PM, Marko Rauhamaa <marko at pacujo.net> wrote:
> Terry Reedy <tjreedy at udel.edu>:
>
>> On 1/13/2015 1:13 AM, Chris Angelico wrote:
>>>>>> def f(): sys.setrecursionlimit(sys.getrecursionlimit()+1) or f()
>>> ...
>>>>>> f()
>>> Segmentation fault
>>>
>>> But otherwise, yes. You shouldn't be able to segfault Python with
>>> Python code.
>>
>> I would have expected an out-of-memory error. If there is not already
>> a crash issue on the tracker for this, you could add one.
>
> Linux grants memory it doesn't have. The truth comes out as a
> segmentation fault. Call it modern banking.

I'm not sure it's a Linux problem. The same thing happens on Windows,
only without the "Segmentation fault" line. The exact behaviour on
stack overflow would depend on the layout of memory... back when I
wrote real-mode single-segment programs in DOS, the standard layout
was PSP, then code, then data, then stack, so overusing the stack
would overwrite your static data (and then, if you're really bad, your
code as well... things got fun then). My best guess now would be that
there's an actual boundary to the stack, and trying to access beyond
that triggers an immediate error - "you're not allowed to use that
memory". Nothing to do with over-allocating memory.

> The code above, though, shouldn't consume memory since it is a simple
> tail-recursive loop.

Only if the interpreter can optimize it away. Bear in mind that it
doesn't _return_ the result of that expression, so it needs to take
whatever f() returns, discard it, and return None. But I could have
defeated that, if I'd wanted to, by coding it to reduce the recursion
limit again after the call - it can't optimize away a non-tail-call.
Point is, if you take away the recursion limit, you _can_ crash
CPython. Likewise if you fiddle around with ctypes:

$ python3
Python 3.5.0a0 (default:1c51f1650c42+, Dec 29 2014, 02:29:06)
[GCC 4.7.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> ctypes.cast(id(1), ctypes.POINTER(ctypes.c_int))[6]=2
>>> 1
Segmentation fault

Not a bug. just a gun that you can shoot yourself in the foot with.

(Code nicked from
http://www.reddit.com/r/Python/comments/2441cv/can_you_change_the_value_of_1/
- from a comment saying "changing 1 this way just destroys
everything". Yep, it does, and pretty quckly too.)

ChrisA



More information about the Python-list mailing list