PHP Internals わいわい #1をやりました #phpinternals_waiwai
TOP > てきとうにこらむ > ゲーム作りとプログラミング日記 > PHP Internals わいわい #1をやりました #phpinternals_waiwai
PHP Internals わいわい #1 をやりました
去る6月3日にPHP Internals わいわいという勉強会をやりました。https://phpinternals-waiwai.connpass.com/event/320134/
動機
ゼロとは言わないがPHP Internalsへのコントリビュートの話がめっぽう聞かれなかったことと、そもそもPHPのコンパイルしたことある?からtadsanさんと話してたのがきっかけでした。使うだけではなく貢献する事も考えてほしいというふうに思ってのことです。
趣旨
コンパイルくらいはできるようになってほしいので、スタイルとしては勉強会というかハンズオン形式にしました。懇親会すらなしでやってもらう形としました。 慣れたらオンラインでできるようにしたいです。
内容
PHP Internals Bookを踏襲していますが、そんなに本編でてこなかった。
こちらでコンパイルを試してみるのが良いでしょう。macOSでもWindowsでもコンパイルは出来はしますが、おまじないのようなものが必要なのでこういう形でやっておいたほうがいいかなと思いました。
デバッグについて
GDBでのデバッグ方法も内容に入れました。var_dump関数が一番わかりやすいかと思います。なぜかと言うと、C言語は静的型付け言語でありますが、PHPは動的型付け言語で、Cで変数の網羅を表現するにはちょうどよい関数であるのです。
コマンド | 説明 |
---|---|
n | ステップオーバー |
b | ブレークポイント |
s | ステップイン |
c | 次のブレークポイントへ |
r | 実行 |
l | 周辺行を見られる |
bt | バックトレース |
ext/standard/var.c
にvar_dump関数の実装があります。以下のように b php_var_dump
でブレークポイントを設定します。すると r -r var_dump(1);
で実際にデバッグができるようになります。
root@b0f2f98cab4b:/# cd /root/php-src/
root@b0f2f98cab4b:~/php-src# gdb sapi/cli/php
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "aarch64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from sapi/cli/php...
warning: File "/root/php-src/.gdbinit" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
To enable execution of this file add
add-auto-load-safe-path /root/php-src/.gdbinit
line to your configuration file "/root/.config/gdb/gdbinit".
To completely disable this security protection add
set auto-load safe-path /
line to your configuration file "/root/.config/gdb/gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual. E.g., run from the shell:
info "(gdb)Auto-loading safe path"
warning: File "/root/php-src/sapi/cli/php" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
(gdb) b php_var_dump
Breakpoint 1 at 0x6adbf4: file /root/php-src/ext/standard/var.c, line 93.
(gdb) r -r 'var_dump(1);'
Starting program: /root/php-src/sapi/cli/php -r 'var_dump(1);'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".
Breakpoint 1, php_var_dump (struc=0xfffff52130d0, level=1) at /root/php-src/ext/standard/var.c:93
93 int is_ref = 0;
(gdb) l
88
89 PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */
90 {
91 HashTable *myht;
92 zend_string *class_name;
93 int is_ref = 0;
94 zend_ulong num;
95 zend_string *key;
96 zval *val;
97 uint32_t count;
(gdb)
バックトレースは以下のようにすればよいです。
(gdb) bt
#0 php_var_dump (struc=0xfffff52130d0, level=1) at /root/php-src/ext/standard/var.c:93
#1 0x0000aaaaab14e81c in zif_var_dump (execute_data=0xfffff5213080, return_value=0xffffffffdb28) at /root/php-src/ext/standard/var.c:229
#2 0x0000aaaaab2bf964 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER () at /root/php-src/Zend/zend_vm_execute.h:1287
#3 0x0000aaaaab34dad4 in execute_ex (ex=0xfffff5213020) at /root/php-src/Zend/zend_vm_execute.h:57364
#4 0x0000aaaaab35235c in zend_execute (op_array=0xfffff5288000, return_value=0xffffffffde30) at /root/php-src/Zend/zend_vm_execute.h:62776
#5 0x0000aaaaab258138 in zend_eval_stringl (str=0xaaaaac336800 "var_dump(1);", str_len=12, retval_ptr=0x0, string_name=0xaaaaac0daf80 "Command line code") at /root/php-src/Zend/zend_execute_API.c:1326
#6 0x0000aaaaab258304 in zend_eval_stringl_ex (str=0xaaaaac336800 "var_dump(1);", str_len=12, retval_ptr=0x0, string_name=0xaaaaac0daf80 "Command line code", handle_exceptions=true)
at /root/php-src/Zend/zend_execute_API.c:1368
#7 0x0000aaaaab258384 in zend_eval_string_ex (str=0xaaaaac336800 "var_dump(1);", retval_ptr=0x0, string_name=0xaaaaac0daf80 "Command line code", handle_exceptions=true)
at /root/php-src/Zend/zend_execute_API.c:1378
#8 0x0000aaaaab4242a8 in do_cli (argc=3, argv=0xaaaaac336780) at /root/php-src/sapi/cli/php_cli.c:996
#9 0x0000aaaaab424e78 in main (argc=3, argv=0xaaaaac336780) at /root/php-src/sapi/cli/php_cli.c:1340
感想
コンパイルできるようになって良かったです。デバッグのやり方も教授できてよかったです。つぎもやりましょう。