Slide 1

Slide 1 text

PHP 本体のバグを見つけたら 適切に報告しよう 工藤 剛

Slide 2

Slide 2 text

● 社会人 6 年目 ● モバイルゲーム会社勤務 ○ お仕事で PHP 利用中 ■ たまに php-src にコントリビュートしたり OSS 出したりも ● 興味対象 ○ PHP ○ 自作キーボード ○ 電子工作 自己紹介

Slide 3

Slide 3 text

PHP のバグを踏んだことは ありますか?

Slide 4

Slide 4 text

では... バグ報告しましたか?

Slide 5

Slide 5 text

ぶっちゃけ難しい!

Slide 6

Slide 6 text

● 実行環境の情報 ○ バージョン ○ OS ○ etc ● 再現コード バグ報告に必要なもの 簡単なバグなら これだけで十分だが...

Slide 7

Slide 7 text

特定の状況下でしか発生しないバグも多い ● 数リクエスト処理後に発生 ● 数時間すると発生 ● OPcache 有効時にのみ発生 ● etc… だいたいの不具合はより複雑 再現できないバグは 修正できない!

Slide 8

Slide 8 text

● デバッグビルドでの検証結果 ○ 拡張の有効・無効状態の詳細 ○ 実行環境情報 ○ スタックトレース バグ報告するときに更に役立つもの

Slide 9

Slide 9 text

● デバッグビルドでの検証結果 ○ 拡張の有効・無効状態の詳細 ○ 実行環境情報 ○ スタックトレース バグ報告するときに更に役立つもの

Slide 10

Slide 10 text

デバッグビルド とは

Slide 11

Slide 11 text

バグを見つけやすい形でビルドされた PHP 基本的にバイナリで提供されていない=自分でビルドが必要 デバッグビルド版 PHP

Slide 12

Slide 12 text

PHP のビルドは 難しいって聞いたんだけど...

Slide 13

Slide 13 text

Debian 系ならこれだけ 踏んだバグの部分に応じて 適宜ライブラリを追加 & 拡張を有効化 (PDO など) 最低限のビルドならそんなに難しくない $ sudo apt-get update $ sudo apt-get install -y build-essential autoconf autotools-dev re2c bison git $ git clone https://github.com/php/php-src $ cd php-src $ ./buildconf --force $ ./configure --disable-all --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --enable-debug $ make -j$(nproc) $ ./sapi/cli/php

Slide 14

Slide 14 text

もっと簡単に!

Slide 15

Slide 15 text

$ docker run --rm -it php:8.3.0-cli /bin/bash # php -r 'var_dump(range(9.9, "0"));' Segmentation fault PHP 8.3.0 のバグを再現してみる

Slide 16

Slide 16 text

# docker-php-source extract # cd /usr/src/php # ./configure --disable-all --enable-debug # make -j$(nproc) # ./sapi/cli/php -v PHP 8.3.0 (cli) (built: Mar 8 2024 12:56:02) (NTS DEBUG) Copyright (c) The PHP Group Zend Engine v4.3.0, Copyright (c) Zend Technologies # ./sapi/cli/php -r 'var_dump(range(9.9, "0"));' Segmentation fault そこからデバッグビルド版にする

Slide 17

Slide 17 text

# apt-get update # apt-get install -y gdb # gdb --args ./sapi/cli/php -r 'var_dump(range(9.9, "0"));' (gdb) run Starting program: /usr/src/php/sapi/cli/php -r var_dump\(range\(9.9,\ \"0\"\)\)\; [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. zif_range (execute_data=0xfffff7a130f0, return_value=0xfffff7a13070) at /usr/src/php/ext/standard/array.c:2963 2963 unsigned char low = (unsigned char)Z_STRVAL_P(user_start)[0]; gdb を入れてスタックトレースを取る 原因の行まで 特定できた!

Slide 18

Slide 18 text

gdb の画面で “backtrace” 詳細なバックトレースを出力

Slide 19

Slide 19 text

もっと見やすく!

Slide 20

Slide 20 text

PHP (php-src) には gdb 用の補助スクリプトが同梱されている ネストした PHP スクリプトも簡単にトレースできる # gdb --command /usr/src/php/.gdbinit --args ./sapi/cli/php zbacktrace

Slide 21

Slide 21 text

ごく稀に発生するやつは どうする?

Slide 22

Slide 22 text

gdb はコアダンプからもスタックトレースを解析できる! # gdb <実行ファイルのパス> <コアダンプのパス> --command <.gdbinit へのパス> コアダンプを取って解析する

Slide 23

Slide 23 text

プロダクション環境に デバッグビルドを入れるの 困難では?

Slide 24

Slide 24 text

頑張るしかない... おすすめは canary 環境にデバッグビルドの PHP を 仕込んでおき流量をコントロール canary 環境は APM 等入れていて遅くなっていることが多いので まだ許容できることが多い (はず) コアダンプ取りにくい問題

Slide 25

Slide 25 text

● バグ報告怖くない! ○ ここまで詳細にレポートできなくてもとにかく上げるのが大事 ○ 報告されなかったばかりに放置されている不具合もあった ■ DateTime 周り https://github.com/php/php-src/pull/11473 ● やってみようという心意義を大切に! ● わからなければ聞いてください! ○ X: https://x.com/zeriyoshi やろうよ!バグ報告