Writing

Feed Software, technology, sysadmin war stories, and more.

Saturday, October 1, 2011

Blowing Python's stack with excessive recursion

This is kind of fun:

$ Z=52372; echo '#!/usr/bin/env python' > crash2.py; for i in `seq 1 $Z`; do echo "if None: pass"; done >> crash2.py ; chmod a+rx crash2.py ; ./crash2.py

$

Nothing happens, right? But, just add one more "if", and...

$ Z=52373; echo '#!/usr/bin/env python' > crash2.py; for i in `seq 1 $Z`; do echo "if None: pass"; done >> crash2.py ; chmod a+rx crash2.py ; ./crash2.py

Segmentation fault

Kaboom! gdb says Python blows up in Python/compile.c with stackdepth_walk() calling itself seemingly forever.

What this means is with the default 8192K stack and this particular assortment of config details on my system, it blows the stack after 52,372 if blocks.

This came up when a friend was trying to benchmark something by just adding a whole bunch of calls to something to his code. It blew up spectacularly, leading to our investigation and this finding.

Not surprisingly, something that does a recursive function call ran out of stack space after an excessive number of calls. Such is life.