きっかけ
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 にわたす引数は次の記事がたいへん参考になった!