Upgrade to Pro — share decks privately, control downloads, hide ads and more …

php-src debug マニュアル

onopon
March 07, 2024

php-src debug マニュアル

https://github.com/onopon/php_build_environment

https://fortee.jp/phperkaigi-2024/proposal/26fcb764-0a5a-4759-9cb7-d8f14814e97a

php-src。それはPHP言語のソースコードのことです。
そのため全て読むのは大変です。
php-srcを読む際、適当なtest.phpを作り、ast\parse_codeを利用しながら気になる挙動の構造を確認したり、気になるfunctionにブレークポイントを仕込んでdebugしていくこととなるでしょう。

しかし、debug環境を整えようとすると、一筋縄ではいかないことが多々あります。少なくとも経験の浅い僕にとっては簡単ではありませんでした。
MacやWindowsなど、デバッグを試す環境の違いにより色々な知見を得ながら環境整備しなければなりません。
それだけの労力を割きながら、いざphp-srcのmake testをしてFailだらけになると気が滅入ってしまうものです。

そこで、Dockerを利用してphp-srcのためのsandbox環境を整えました(発表当日にはgithub上でpublicリポジトリとして公開します)。
本セッションでは、そんなsandbox環境とVSCodeを連携方法や、それらを用いたfunctionへのアプローチ(debug)方法をお伝えいたします。

もうphp-srcの環境構築に迷うことはありません。
素敵なphp-srcリーディングライフを送りましょう!

対象者: php-srcを読んでみたい方/読もうとしたけど環境構築で挫折した方

onopon

March 07, 2024
Tweet

More Decks by onopon

Other Decks in Programming

Transcript

  1. 自己紹介 株式会社ウエディングパーク Photorait 本部 おのぽん(@onopon_engineer) ・2022年6月にウエディングパークに入社 ・前職では   - 大規模ソーシャ ゲームのサーバエンジニア

      - 人工知能コミュニケーション ボットのサーバ全般   - Androidアプ 開発  を行い、業務でのPHP開発は未経験 ・エンジニア以外の時は大体卓球をしています🏓 ・パ 卓球選手のコーチもしており、  今年のパ パ ンピックでの活躍を目指し日々奮闘中 ・今月末もポー ンドに行ってきます😇󰐤 3
  2. 14 突然ですが、問題です。 A: [] B: [''] C: [null] explode(',', '1,2');

    を実行すると [1,2] が返ってきます。 では、 explode(',', ''); の返り値は次の3つのうちどれでしょうか?
  3. 26 「php-src ビ ド mac」で検索 brew install hoge × n

    あれ、installうまくいかないぞ・・・ エ ー解消方法検索しないと😇 ./configure コマンドが通らない・・・ path指定やオプションが必要なのか。。 make -j4 成功してくれ・・・
  4. 28

  5. 29

  6. 30

  7. 31

  8. 32

  9. 38 php_build_environment でphp-srcをデバッグする環境を整える手順 • Docker をインストー する • Visual Studio

    Codeをインストー する • php_build_environment をcloneする • php_build_environment 内にある initial_run.sh を実行する ◦ sh ./initial_run.sh 以上。
  10. 39 initial_run.sh により行われること • php-src のclone(ブ ンチはmaster) • デバッグ用のdockerコンテナ「sandbox」の構築 •

    sandbox上でphp-srcのbuild • php-srcに ◦ テスト用のファイ test.phpとast_parse_test.phpを設置 ▪ 後ほど解説 ◦ .vscode ディ クト を設置
  11. 40 sandbox コンテナについて • コンテナのベースは ubuntu: 23.10 • 必要なミド ウェアをインストー

    ◦ デバッグに必要なgdbを利用可能な状態に ◦ php-astもこのタイミングでインストー • volume: php_build_environment 配下 ◦ なので、php-srcのファイ をコンテナ外から書き換えても大丈夫
  12. 51 この時にPHPが行っていること SAPI = Zend Engineを呼び出すためのインターフェース (mod_php, php-fpm, cli etc…)

    Zend Engine:PHP スク プトを実行するエンジン ・スク プトを解析してAST化 ・ASTからOpcodeを生成 ・Opcodeより適切なHandlerを呼び出す アウトプット
  13. 52 この時にPHPが行っていること SAPI = Zend Engineを呼び出すためのインターフェース (mod_php, php-fpm, cli etc…)

    Zend Engine:PHP スク プトを実行するエンジン ・スク プトを解析してAST化 ・ASTからOpcodeを生成 ・Opcodeより適切なHandlerを呼び出す アウトプット この辺りをおさえれば デバッグできそう
  14. SAPI = Zend Engineを呼び出すためのインターフェース (mod_php, php-fpm, cli etc…) Zend Engine:PHP

    スク プトを実行するエンジン ・スク プトを解析してAST化 ・ASTからOpcodeを生成 ・Opcodeより適切なHandlerを呼び出す アウトプット この辺りをおさえれば デバッグできそう AST この時にPHPが行っていること 53
  15. 55 Syntax Tree → Abstract Syntax Tree echo("HOGE"); echo (

    "HOGE" ) ; Source Code Syntax Tree Abstract Syntax Tree echo "HOGE"
  16. 56 ZendEngineでのAST typedef uint16_t zend_ast_kind; typedef uint16_t zend_ast_attr; struct _zend_ast

    { zend_ast_kind kind; /* Type of the node (ZEND_AST_* enum constant) */ zend_ast_attr attr; /* Additional attribute, use depending on node type */ uint32_t lineno; /* Line number */ zend_ast *child[1]; /* Array of children (using struct hack) */ }; Zend/zend_ast.h
  17. 57 ZendEngineでのAST typedef uint16_t zend_ast_kind; typedef uint16_t zend_ast_attr; struct _zend_ast

    { zend_ast_kind kind; /* Type of the node (ZEND_AST_* enum constant) */ zend_ast_attr attr; /* Additional attribute, use depending on node type */ uint32_t lineno; /* Line number */ zend_ast *child[1]; /* Array of children (using struct hack) */ }; Zend/zend_ast.h kind: astの種類 attr: 付属情報 lineno: 行番号 child: 子ノード kindとchildだけ抑えれば一旦大丈夫
  18. SAPI = Zend Engineを呼び出すためのインターフェース (mod_php, php-fpm, cli etc…) Zend Engine:PHP

    スク プトを実行するエンジン ・スク プトを解析してAST化 ・ASTからOpcodeを生成 ・Opcodeより適切なHandlerを呼び出す アウトプット この辺りをおさえれば デバッグできそう Opcode この時にPHPが行っていること 63 Handler
  19. 65 PHPのOpcodeはopcacheモジュー のデバッグの設定をすると確認できる $ sapi/cli/php\ -d opcache.opt_debug_level=0x10000\ -d opcache.enable_cli\ -d

    zend_extension=$(pwd)/modules/opcache.so\ test.php Visual Codeでデバッグすると下記が実行される
  20. 66 PHPのOpcodeはopcacheモジュー のデバッグ実行時 $_main: ; (lines=2, args=0, vars=0, tmps=0) ;

    (before optimizer) ; /src/php-src/test.php:1-2 ; return [] RANGE[0..0] 0000 ECHO string("HOGE") 0001 RETURN int(1)
  21. 67 PHPのOpcodeはopcacheモジュー のデバッグ実行時 $_main: ; (lines=2, args=0, vars=0, tmps=0) ;

    (before optimizer) ; /src/php-src/test.php:1-2 ; return [] RANGE[0..0] 0000 ECHO string("HOGE") 0001 RETURN int(1)
  22. 70 echoメソッドのhandlerは3つ用意されている(挙動はほとんど変わらない) echo("HOGE"); echo("HO"."GE"); ZEND_ECHO_SPEC_CONST_HANDLER デバッグ出力 0000 ECHO string("HOGE") 0001

    RETURN int(1) $var = "HOGE"; echo($var); ZEND_ECHO_SPEC_CV_HANDLER デバッグ出力 0000 ASSIGN CV0($var) string("HOGE") 0001 ECHO CV0($var) 0002 RETURN int(1) $ho = "HO"; echo($ho."GE"); ZEND_ECHO_SPEC_TMPVAR_HANDLER デバッグ出力 0000 ASSIGN CV0($ho) string("HO") 0001 T2 = CONCAT CV0($ho) string("GE") 0002 ECHO T2 0003 RETURN int(1)
  23. 74 まとめ • php_src_environment を用意し、デバッグ環境を整備 ◦ https://github.com/onopon/php_build_environment • PHPはスク プトをAST化→OPCodeを生成→Handlerの呼び出しにより実行される

    ◦ ast_parse_test.php によりast構造を確認できる ◦ Zend/zend_compile.c の zend_compile_stmt メソッドにブ ークポイントを貼れ ばAST化後の流れを追える ◦ Zend/zend_vm_execute.h 内で ZEND_{Opcode} と検索するとHandlerを見つ けることができる ▪ そこにブ ークポイントを貼れば振る舞いの流れを追える onopon php_build_environment
  24. 77 本資料作成にあたり参考にさせていただいた記事 php-srcを読んでみよう by 田実 誠 https://fortee.jp/phpcon-2022/proposal/1addf51d-6f72-4c96-9337-034ec6cc0643 PHPのOpcodeを 読んでみよう https://speakerdeck.com/yasuaki640/phpnoopcodewo-du-ndemiyou

    PHP AST 徹底解説 https://www.slideshare.net/do_aki/php-ast php-src の歩き方 https://www.slideshare.net/do_aki/phpsrc php and sapi and zendengine2 and... https://www.slideshare.net/do_aki/php-and-sapi-and-zendengine2-and PHP と SAPI と ZendEngine3 と https://www.slideshare.net/do_aki/php-sapi-zendengine3 [php-src読書録]その1: CLI実行からスク プト実行まで https://blog.freedom-man.com/php_src_1 深入理解Zend执行引擎(PHP5) https://gywbd.github.io/posts/2016/2/zend-execution-engine.html How PHP engine builds AST https://dev.to/mrsuh/how-php-engine-builds-ast-1nc4 How to dump and inspect PHP OPCodes https://php.watch/articles/php-dump-opcodes