Building PHP with Debug symbol on Docker

きっかけ

Docker 上の PHP でとあるテストを行っていたところ、いきなり Segmentation fault で落ちるという事件が発生。 このレベルで落ちたときは gdb をつかって調査するのだが、gdb で開いたら "No debug symbol found" と言われてしまった。

TL;DR

[1] Clone official docker image repo

$ git clone https://github.com/docker-library/php
$ cd 7.2/alpine3.10/cli/

[2] Add --enable-debug to configure options

--- a/7.2/alpine3.10/cli/Dockerfile
+++ b/7.2/alpine3.10/cli/Dockerfile
@@ -117,6 +117,7 @@ RUN set -eux; \
        cd /usr/src/php; \
        gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
        ./configure \
+               --enable-debug \
                --build="$gnuArch" \
                --with-config-file-path="$PHP_INI_DIR" \
                --with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \

[3] Build docker image

$ docker build -t php72-debug .
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM php:7.2-cli-alpine
+FROM php72-debug

[4] Debug with gdb

$ ulimit -c unlimited  # Enable coredump
$ php /path/to/segv.php 
...
Segmentation fault

$ apk add gdb
$ gdb php --core /path/to/coredump --command /usr/src/php/.gdbinit

手順

Debug Symbol がONになった Docker image がほしい。

Debug Symbol をONにするには、--enable-debug 引数を configure のときに追加すればいいらしい。

しかし、 Docker Hub にある Official Image は --enable-debug はついてないので、この Dockerfile を丸々取ってきて、--enable-debug だけを追加してビルドし直した。

$ git clone https://github.com/docker-library/php
$ cd 7.2/alpine3.10/cli/
--- a/7.2/alpine3.10/cli/Dockerfile
+++ b/7.2/alpine3.10/cli/Dockerfile
@@ -117,6 +117,7 @@ RUN set -eux; \
        cd /usr/src/php; \
        gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
        ./configure \
+               --enable-debug \
                --build="$gnuArch" \
                --with-config-file-path="$PHP_INI_DIR" \
                --with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
$ docker build -t php72-debug .

ビルドした Image を使って gdb でデバッグしたい

Image ができたら、あとはこれを FROM になるように差し替えて、

--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM php:7.2-cli-alpine
+FROM php72-debug

gdb を入れて、core dump をデバッグすればよい。

$ ulimit -c unlimited  # Enable coredump
$ php /path/to/segv.php 
...
Segmentation fault

$ apk add gdb
$ gdb php --core /path/to/coredump --command /usr/src/php/.gdbinit

gdb にわたす引数は次の記事がたいへん参考になった!

qiita.com