vsespb has asked for the wisdom of the Perl Monks concerning the following question:

Recently I found that if I run:

perl -e 'sub x { x() }; x()'
on modern linux box, whole system locks - keyboard, mouse does not work.

I asked several people to reproduce the problem. Also tested on virtual machine.

So, Ubuntu 12.04 - not affected at all. Can terminate script by Ctrl-C.

Ubuntu 16.04 - locks up. Only chance to quit is to power off the machine (or wait till it fills all memory; or maybe REISUB - didn't try this ). I reported this a bug to Ubuntu team. They confirmed that 16.04 indeed locks up.

Debian (7 or 8, dont remember) is less responsive than Ubuntu 12.04, but still can quit.

One person told that Fedora (I suspect modern) locks up too.

MacOSX not affected.

Ubuntu team qualified this bug report as perl problem (well, that does not necessary means that it will be considered as valid bug), I was going to object, but interesting thing, indeed, not every programming language can cause such trouble. I tried Ruby an C, they use C-stack thus simply run out of stack very fast and nothing bad happens.

Question: do you have any thoughts why modern OSes are not friendly to persons running buggy perl code (perhaps it's a developer, who debugs the code)? Maybe perl uses some memory allocation which is not "compatible" with modern kernels? Maybe linux kernel changed some defaults, related to process priorities? How linux can be tuned to avoid this (tried nice and ionice - does not help)?

Solution to install SIG WARN and terminate on "Deep recursion" is understood.

Replies are listed 'Best First'.
Re: Perl Deep Recursion locks up modern linuxes?
by dave_the_m (Monsignor) on Oct 09, 2016 at 17:24 UTC
    Perl's execution stack is malloced() from the heap rather than using the C stack, so infinite recursion just means perl keeps mallocing memory. My general experience with runaway processes on Linux is that the machine grinds to a complete halt (with not even the cursor moving) for several minutes until the process dies or is killed, then things slowly come back to normal (as swapped out memory is brought back in).

    If it's just a malloc() problem, then something like

    perl -e'push @a, 1 while 1'
    should kill the machine just as easily,

    Dave.

      Back when Re: Not able to release memory (malloc implementation) was written, glibc 2.x based Linux systems used ptmalloc, which is based on Doug Lea's malloc. This version of malloc uses mmap(2), rather than sbrk(2), when the chunk of memory requested is larger than some threshold value (typically 128K). So, an interesting test would be to adjust Dave's little memory eater program above to repeatedly push "large" strings (greater than 128K, say) and see if that makes any difference to machine lockup behaviour.

      Further things you might try:

      • Take Perl out of the equation. Write a small C program that just keeps on malloc'ing strings of various sizes and see if running such a program locks up the whole machine.
      • Build a custom perl with an instrumented/different version of malloc to help you debug what is going on.
      • Check version history of the Linux/glibc C sources to try to find the change that triggered this new "machine lockup" behavior.

      Yes, your code example freezes machine same way. So you experience this all the time? My experience that it never freeze such way before (I used Ubuntu 12, 10, 9, 8 last 10 years after switching from Windows).
        So you experience this all the time?
        It's been my general experience with Linux for many years. In olden times it used to be the OOM killer killing off random processes that made the machine unusable - I don't know whether they've improved it.

        The usual scanario is that I'm investigating a leak in the perl core, or have just introduced one (I'm a core developer), and if i don't spot that I have a problem, I find the UI going very slowly, at which point I madly try to bring the cursor into the right terminal window and ^C repeatedly. About half the time I end up having to reboot the machine.

        I use Fedora.

        Dave.

Re: Perl Deep Recursion locks up modern linuxes?
by BrowserUk (Patriarch) on Oct 09, 2016 at 16:57 UTC

    What happens if you turn off safe signals: set PERL_SIGNALS=unsafe?

    If that allows ^C to interrupt the recursion; you then need to look at what has changed in the kernel that affects that difference in code path.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
      .. but just in case I tried export PERL_SIGNALS=unsafe. Does not help.
      I don't think it's related to signals, whole system freezes - Ctrl-Alt-F1 (switch to root console), Ctrl-Alt-Del, screen, mouse. Nothing works. Mouse does not move, screen does not update. For example if you turn on/off laptop charger or terminate wifi, charger/wifi icon will not update. It's reproducible on real hardware and on Virtual box VM (of course only guest system freezes), and confirmed by Ubuntu team member.

        Ouch! And very strange.