DEV Community

Yury G.
Yury G.

Posted on

Getting a Core Dump in PHP Docker container

PHP is failing with SIGSEGV

It could be not a common situation, but sometimes you start your PHP container and at some point PHP-FPM is failing showing an error log like:

NOTICE: fpm is running, pid 1
NOTICE: ready to handle connections
WARNING: [pool www] child 7 exited on signal 11 (SIGSEGV - core dumped) after 245.799183 seconds from start
Enter fullscreen mode Exit fullscreen mode

It is a Segmentation Fault. There could be a various reasons for that. The cause of that could be an incompatibility of some PHP Extensions, or even a PHP code executing in some specific edge cases.

Core Dump

To understand the real root cause of SIGSEGV is to backtrace the core dump with GDB and/or Valgrind.

Just to note, this article is not about how to use GDB/Valgrind to find why segfault happens, but how to prepare for it.

Problem #1

In my case, there was no core dump, nowhere. Probably, you may have the same case.
To check where core dump should be saved you could runt he command:

cat /proc/sys/kernel/core_pattern
Enter fullscreen mode Exit fullscreen mode

In my case the output was:

|/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E
Enter fullscreen mode Exit fullscreen mode

So it means that core dump is piped to apport, but for some reason it's not resulted in a core dump saved to a file.

I am using php8.2-fpm-alpine3.18 (now) and php8.0-alpine3.12 (before) Docker images. But it seems majority (if not all) Alpine images has the same problem.

Solution #1

You need to do a few changes to let Docker image properly save the core dump.

  1. In your Docker entry point file, please add the following lines before the last exec statement:

    ulimit -c unlimited
    echo '/tmp/core' > /proc/sys/kernel/core_pattern
    echo 1 > /proc/sys/fs/suid_dumpable
  2. In the docker-compose.yml find your PHP service and update the file so it will look like this (of course, omit >>> and <<<):

        privileged: true
          core: 99999999999
  3. Rebuild the image.

  4. Now, when segfault will happen you should be able to find it in /tmp directory. A core dump file will be named like /tmp/core.7, where the number corresponds to the number of a PHP-FPM worker failed.

Problem #2

Great! Now we have core dump and could debug it.

But why we have a problem #2?
The problem is in PHP binaries that have no debug symbols. It's absolutely normal to strip these symbols after compilation, as this saves a memory and improves performance. No one wants to have a fat and slow PHP binaries in production environment!

However, debugging without debug symbols is a total disaster.

Solution #2

Well, long story short - you need to recompile PHP and do not strip debug symbols. Here are the steps:

  1. Checkout Git repository of Docker PHP images:

    git clone
    cd php
  2. Go into directory where relevant Dockerfile is located. If you are using PHP 8.2 under Alpine Linux, the path should be:

    cd 8.2/alpine3.18/fpm
  3. Now open Dockerfile and find following lines:

    find \
        /usr/local \
        -type f \
        -perm '/0111' \
        -exec sh -euxc ' \
            strip --strip-all "$@" || : \
        ' -- '{}' + \
    ; \
  4. Completely delete these lines out of Dockerfile and save it.

  5. Build the image and tag it:

    docker build -t php-fpm-debug .
  6. Now you have an image with PHP compiled with debug symbols. What's next? Yes, build your app image from this one!

  7. In Dockerfile of your app replace FROM ... with FROM php-fpm-debug:latest.

  8. Build it! But be aware to not use --pull argument, so docker will search local repository for the specified image.


Now, if segfault will happen you will be able to find core dump in /tmp directory and it will contain debug symbols for easier debugging process.

P.S. If you know a good article or tutorial on how to use GDB or Valgrind to debug PHP core dumps, please leave in a comment below. Much appreciated!

Top comments (0)