Monday, November 14, 2016

Gotcha of the Day: More WordPress 4.6 Segfault Challenges

A few months back I had a client's WordPress site that started segfaulting when I upgraded to WordPress 4.6. I wrote it off as a quirk in the server. Perhaps there was some old low level library that was causing things to crash.

We finally got around to upgrading the serving, including: Apache 2.4 to 2.6, PHP 5.3 to 5.6, 32 bit OS to 64 bit OS and CentOS to Debian. The server was in test mode and I eagerly clicked the upgrade button to bring WordPress up to the latest version (now 4.6.1).

The home page rendered fine, but an internal page crashed. More segfaults!

[Mon Nov 14 14:33:05.945020 2016] [core:notice] [pid 21979] AH00052: child pid 11408 exit signal Segmentation fault (11)
[Mon Nov 14 14:33:05.945114 2016] [core:notice] [pid 21979] AH00052: child pid 11421 exit signal Segmentation fault (11)
[Mon Nov 14 14:34:06.022689 2016] [core:notice] [pid 21979] AH00052: child pid 11427 exit signal Segmentation fault (11)
[Mon Nov 14 14:34:07.023865 2016] [core:notice] [pid 21979] AH00052: child pid 11433 exit signal Segmentation fault (11)
[Mon Nov 14 14:34:08.024998 2016] [core:notice] [pid 21979] AH00052: child pid 11425 exit signal Segmentation fault (11)
[Mon Nov 14 14:34:08.025065 2016] [core:notice] [pid 21979] AH00052: child pid 11434 exit signal Segmentation fault (11)
[Mon Nov 14 14:34:09.032498 2016] [core:notice] [pid 21979] AH00052: child pid 11435 exit signal Segmentation fault (11)

How could this be? PHP isn't supposed to segfault, and certainly changing high level code in WordPress shouldn't trigger a segfault. And I was no running and an up to date system, so my theory of an ancient library causing problems didn't make sense.

A few months back when I had this issue I went the route of trying to analyze the core dump. Given that I had one page that was working and one that wasn't, I decided instead to focus on figuring out which chunk of high level PHP was breaking.

I did the usual debugging dance: I confirmed that /foo crashed with a segfault. I then removed all the custom plugin code I'd written and confirmed that /foo came up. Of course without the plugin code /foo no longer did anything, but at least it didn't segfault.

I then took my time moving these two goal-posts closer, and closer together. After about 20 minutes I had the one line of code that was crashing WordPress:

 add_filter('the_title', function($title, $id) {
 if($id == get_the_ID() && strpos(get_the_content(), '{sometext}') !== false) {
   ...

Calling get_the_content from within the_title filter was causing a segfault. I suppose I could have dug deeper to figure out why, but instead, I changed my code around to read:

 add_filter('the_title', function($title, $id) {
  $the_post = get_post();
  if($id == $the_post->ID && strpos($the_post->post_content, '{sometext}') !== false) {
   ...

For my purposes, this code works.

Is this related to the original segfault issue I ran into? It seems unlikely, but then again, who ever heard of WordPress causing a segfault? So crazy. I'm just glad I was able to fix it with relative ease.

No comments:

Post a Comment