PHP recursion and Apache segmentation faults

Published June 26th, 2005

Although I’ve been working with PHP for some years now, I’ve never really fussed too much about the internals of the language itself. If it works, I don’t really care to know too much about why. And generally PHP does work.

Then, the other day, I was merrily working away on what I thought was a simple piece of code to convert a structured PHP array into a string (yep — serialization, but for a particular purpose). It was a brief and rather neat little recursive function, and it worked. Well, it did at first. Then when I tried it in a ‘real world’ scenario, I found that all of a sudden, it didn’t work — and not in a nice, neat ‘Oops, you can’t do that’ kind of a way, but in an ‘Oh crap, I’m so broken I’m going to bring Apache down with me’ kind of a way.

So I was getting sementation faults when the array was especially large — although by ‘large’ I only mean a few hundred elements, with a maximum nesting depth of three levels. Nothing too outrageous.

At first I was totally at a loss. Changing random things (an extra space here or there) seemed to fix the problem but then it’d appear again with different data. I tried more and more outlandish fixes but nothing seemed to fix the problem for good. So I began to dig around a bit and discovered one of PHP’s dirty little secrets — it’s not very good at recursion. There aren’t many references to it, although there are several bugs listed (including this very old one with a response from Zeev himself) which tend to be answered with ‘just don’t do it’. Yeah that’ s helpful, thanks.

Seems that PHP uses the stack to store stuff during recursion, and fills it up pretty quickly in doing so. Now obviously all languages have limits, but to be aware (for some years) of one so fundamental, and not at least trap for it (and maybe throw a ‘too much recursion’ error, or somesuch) strikes me as idiotic. It would’ve saved me a day and a half’s detective work trying to identify the problem, at least. No wonder PHP has such a poor reputation among ‘serious’ programmers.

So do I have any wise words of advice to offer anyone in a similar fix? Sorry, no. I ended up rewriting my elegant recursive function as a hideous iterative monstrosity that piggybacks on PHP’s own serialize() function. Apparently you can up the stack size in Apache, or even fiddle with some obscure internal PHP setting and recomiple it to a similar end, but that doesn’t seem like much of a solution to me — just putting the problem off and hoping for the best.

Oh and FYI: I was running my code on PHP5.04, Apache 2 (although it seems clear that the problem applies to all versions of PHP and Apache on Linux). Oh yeah — here’s a kicker: I tried it on my Windows Apache setup and couldn’t reproduce the problem even with a massive array and multiple iterations. Chalk one up for Microsoft!

Get a Trackback link

4 Comments

  1. Ed on September 29, 2005

    My guess for why windows+apache+php doesn’t crash is because you’re almost certainly using php via cgi instead of as an apache module. Since php isn’t embedded in the apache instance it can’t segfault apache. PHP itself might still segfault, though.

  2. Stickman on October 1, 2005

    Nope, it’s running as a module, not CGI. And I can tell it doesn’t segfault because it completes the task rather than borking halfway through.

  3. Execute on November 4, 2005

    can u give us a code example of what you were doing? Becuase i dont quite understand.

  4. bob on December 1, 2006

    Hi! I setup SSL/TLS on apache 2.0.
    Its working fine apache only listen on 443 port for incoming connections. My question is:
    How to config apache , for example when user type http://www.dome.com to automatic redirect him to port 443 and https connection. Now when i use http://www.domain.com he dont display anything because apache don listen on 80.
    Can you help me, please? Thanx :)

Leave a comment

Comment Policy: First time comments are moderated. Please be patient.

OpenID

Anonymous