Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: Oscar Benjamin Newsgroups: comp.lang.python Subject: Re: setrecursionlimit Date: Thu, 19 May 2016 10:27:45 +0100 Lines: 62 Message-ID: References: <573c941f$0$22141$c3e8da3$5496439d@news.astraweb.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Trace: news.uni-berlin.de uyb+EpuvkH2rYOeRLR6FPwVGWN13HFxBfhUBzgJfOhRg== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.001 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'paths': 0.05; 'subject:skip:s 10': 0.05; 'compiler.': 0.09; 'compute': 0.09; 'indeed,': 0.09; 'modules.': 0.09; 'portable': 0.09; 'python- level': 0.09; 'runtime': 0.09; 'segfault.': 0.09; 'stackless': 0.09; 'example:': 0.10; 'python': 0.10; 'exception': 0.13; 'stack': 0.13; "(i'm": 0.16; '(implemented': 0.16; '2016': 0.16; 'assumptions': 0.16; 'heap': 0.16; 'high?': 0.16; 'numpy': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'to:name:python list': 0.16; 'wrote:': 0.16; "wouldn't": 0.16; 'memory': 0.17; 'bytes': 0.18; 'example.': 0.18; 'load': 0.20; 'settings': 0.20; 'extension': 0.20; 'machine': 0.21; 'arguments': 0.22; 'assuming': 0.22; 'either.': 0.22; 'header:In-Reply-To:1': 0.24; 'module': 0.25; "doesn't": 0.26; 'example': 0.26; 'define': 0.27; 'message- id:@mail.gmail.com': 0.27; 'function': 0.28; '(although': 0.29; '(it': 0.29; 'pointer.': 0.29; 'array': 0.29; 'objects': 0.29; 'raise': 0.29; "i'm": 0.30; 'system,': 0.30; 'code': 0.30; 'convention': 0.30; 'e.g.': 0.30; 'query': 0.30; 'operations': 0.31; 'skip:s 30': 0.31; "can't": 0.32; 'url:python': 0.33; 'avoiding': 0.33; 'combination': 0.33; "d'aprano": 0.33; 'steven': 0.33; 'gets': 0.35; 'requirements': 0.35; 'received:google.com': 0.35; 'could': 0.35; 'done': 0.35; 'path': 0.35; 'level': 0.35; "isn't": 0.35; 'supports': 0.35; 'but': 0.36; 'too': 0.36; 'should': 0.36; 'there': 0.36; 'url:org': 0.36; 'received:209.85': 0.36; 'possible': 0.36; 'depends': 0.36; 'url:library': 0.36; 'to:addr:python-list': 0.36; 'subject:: ': 0.37; 'really': 0.37; 'setting': 0.37; 'itself': 0.38; 'received:209': 0.38; 'christian': 0.38; 'skip:o 20': 0.38; 'why': 0.39; 'does': 0.39; 'to:addr:python.org': 0.40; 'space': 0.40; 'called': 0.40; 'url:3': 0.60; 'high': 0.60; 'your': 0.60; 'skip:u 10': 0.61; 'skip:n 10': 0.62; 'more': 0.63; 'limit': 0.65; 'here': 0.66; 'touch': 0.66; 'direct': 0.68; 'high,': 0.84; 'indirect': 0.84; 'oscar': 0.84; 'succeeds': 0.84; 'underneath': 0.84; 'care,': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=k2vVfunXINcM431ShMqkAo0TrMBcf2DXzhpaI3faJmI=; b=LuPIMHNn/mNlb91nc1tNB6+3GpDrW5l0uvHf3j/MHlismwHZnXyZglItiqhQcx9c8o vhpnMLDLyDpCx+SmOpHuUBP9jhp5lS9gorvzD3uoVhorMdwlkWHFZNtFXy9BmNRoKbht RpZ/HQJOWPIjCQukljpNLLnB1YmJyeKfWjdrTWu+jj56XvjIcyBmnBsPd8soEhmp+DHi vs2n1wK3gEDLCBjb7DznN0xkmlR8ety4LqgiHNmjTF/dPcKWGnAW7N17a2av8nUqpkzl gwyJXR98o0HOl0EH078/0hWY4vG3EofeV6GNvd6+71e7G3/78MVY1MV+r0oUI5WUw8G5 KD4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=k2vVfunXINcM431ShMqkAo0TrMBcf2DXzhpaI3faJmI=; b=ho3WVUG3o5PhL1fyMTaj+94Z+TFIpScDfAoVo1V/VcizAuArDakUiq0u5DpXFa17hd W5nnjA2eCTYxWQDQuvZJCg/cbX1NSezkeRSUjVd+lAAW9hNd/x0MICyFkEDCL+juvWvM xKB1P9xTgRGMZI9WpYNlprq7AYd4jApxn9fuBZrv0V6eO+gVZb3u6ZD/CBxzVabc7Q2Y XW3+5vCvr/ZB/L9pbEYeOvgH9XeSd5pt2MNjWMxfA14uAz1ayrFpbYIa4Std4//O00N5 z3gCnHj+iqm4VeggvQuMiPIozfh7ScukW1D8i4LGi8aNs46RHyazLL+XBaY6RMtICXS0 AjqQ== X-Gm-Message-State: AOPr4FUVc0JulIHnKc/iDkImGxwoJ8KaFja744YYo6X/KjpudatEof9scltGF2LC60ZtjaZpmmgbnPrbhivEoQ== X-Received: by 10.112.147.229 with SMTP id tn5mr4214731lbb.120.1463650085773; Thu, 19 May 2016 02:28:05 -0700 (PDT) In-Reply-To: <573c941f$0$22141$c3e8da3$5496439d@news.astraweb.com> X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Mailman-Original-Message-ID: X-Mailman-Original-References: <573c941f$0$22141$c3e8da3$5496439d@news.astraweb.com> Xref: csiph.com comp.lang.python:108824 On 18 May 2016 at 17:11, Steven D'Aprano wrote: > The documentation for setrecursion limit warns against setting the limit too > high: > > [quote] > The highest possible limit is platform-dependent. A user may need to > set the limit higher when they have a program that requires deep > recursion and a platform that supports a higher limit. This should > be done with care, because a too-high limit can lead to a crash. > [end quote] > > https://docs.python.org/3/library/sys.html#sys.setrecursionlimit > > Indeed, if you set the recursion limit too high, you can smash the memory > heap and get a segfault. How exactly does that work? > > Why doesn't setrecursionlimit() raise an exception when you try to set it > too high? For example: > > sys.setrecursionlimit(2000000000) > > succeeds on my system, even though that's a ludicrously high number. (It is > more than half the number of bytes of memory my computer has.) > > > So why can't Python tell if I'm setting the limit too high? > > (I'm assuming that if it could, it would.) It's not altogether impossible to do this but it requires ducking underneath the C level to the machine code level. The C standard doesn't define the exact number of bytes that should be used by a stack frame. The exact number depends on the calling convention used for your OS/hardware/compiler combination and also on the optimisation/debug settings used by the compiler. A good optimiser might be able to completely eliminate your function so that it doesn't touch the stack for example. Also it depends ultimately on the code path that leads to PyEval_EvalFrameEx calling itself recursively. The recursion here is indirect and there are multiple paths for it, depending on whether the function is called with no arguments or whether it is a generator etc. Then after that you need to consider extension modules. For example a numpy array can store Python objects and perform operations on them. If we have an ndarray of Fractions then there's no way at compile time to know how much stack space ndarray.__add__ (implemented with a load of complex C code) will need before calling e.g. Fraction.__add__. Given the extension module case it's clearly impossible to compute the hardware-stack memory requirements of a Python-level frame at compile time. Christian has already explained why this wouldn't really work at runtime either. There isn't even a portable way at the C level to query the current value of the stack pointer. And even if you could you'd have to make hardware-specific assumptions to be able to use that information. My understanding (although I have no direct experience here) is that Stackless Python is an alternative implementation that gets around all of these problems by avoiding the recursion altogether. -- Oscar