can someone explain why this "endless" loop segfaults quickly? For example, let's say we have this function:
#!/bin/bash
foo() {
foo
}; foo
This segfaults after 8-10 seconds. Examining via strace, we can see a lot of brk() calls:
brk(0x2e11000) = 0x2e11000
brk(0x2e12000) = 0x2e12000
brk(0x2e13000) = 0x2e13000
brk(0x2e14000) = 0x2e14000
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x7ffcddf5ff68} ---
+++ killed by SIGSEGV +++
Segmentation fault
My questions are:
The brk
s are not related. It segfaults because it runs out of stack space. If you reduce the available stack with ulimit -s 512; ./yourscript
you'll see that it crashes much quicker.
It gobbles up all stack space because you have an infinitely recursive function and bash does not do tail call optimization.
It already uses malloc
(or a bash specific version thereof). Since malloc
is a C library function and not a syscall, it does not show up in strace
. There is no problem with allocated memory though, it's running out of stack space.
The brk
s are used to store some of the infinite metadata associated with your infinite recursion, but it's not enough to matter.
Crashes in infinitely recursive functions happens in various forms in all languages when you have unbounded recursion that isn't optimized. Try void foo() { foo(); }
in Java, or def foo(): foo()
in Python.