ます’s Blog - どうでもいい記事100選

どうでもいい記事100選

「?:」演算子(続きの続きの続き)

段々とPHPの話題ではなく、gdbの話題になってきていますが。。。気にしないという事で。(w
どこまで「続き」が伸びるか気になるところではありますが、先日の続きです。

iakioさんから「s(step)」と「n(next)」の違いについて補足をいただきました(後、「fin(finish)」についても)。
本当にありがとうございます。<(_ _)>
しかしながら。。。頭が悪い自分では(まだまだ)書いてる事の理解が全然できていないようです。。。せっかく補足をいただいたのにスミマセン。_| ̄|○
ググってみても、大体そんな感じで説明が書かれているけど。。。正直(まだまだ)分からんっす!(>_<)
分かりやすいように図で沢山解説しているページがあると嬉しいんだけどなぁ。。。って、都合良スギ。(w
「今は(まだ)その時期では無いだけで、将来の自分は(きっと)理解できるさ」と前向きに自分を励ましつつ、めげずにがんばっていこう。


気を取り直して、今日やってみた事をつらつらと書いてみます。

ブレーク・ポイントは一つだけじゃなくて複数設定できる事が分かりました。
早速、確認してみる。

% cd $HOME/php-5.3-dev
% gdb ./php-cli
GNU gdb 6.4.90-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".

(gdb) b $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_compile.c:4703
Breakpoint 1 at 0x81f9e05: file $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_compile.c, line 4703.

(gdb) b $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_vm_execute.h:9022
Breakpoint 2 at 0x824cef8: file $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_vm_execute.h, line 9022.

(gdb) i breakpoints
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x081f9e05 in zend_do_jmp_set
                                       at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_compile.c:4703
2   breakpoint     keep y   0x0824cef8 in ZEND_JMP_SET_SPEC_VAR_HANDLER
                                       at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_vm_execute.h:9022

(gdb) r -r '$_GET["user_id"] = "0"; $user_id = $_GET["user_id"] ?: "anonymous";'
Starting program: $HOME/php-5.3-dev/php-cli -r '$_GET["user_id"] = "0"; $user_id = $_GET["user_id"] ?: "anonymous";'
Failed to read a valid object file image from memory.

Breakpoint 1, zend_do_jmp_set (value=0xbfdd0824, jmp_token=0xbfdd0838, colon_token=0xbfdd084c)
    at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_compile.c:4703
4703            opline->opcode = ZEND_JMP_SET;

(gdb) bt
#0  zend_do_jmp_set (value=0xbfdd0824, jmp_token=0xbfdd0838, colon_token=0xbfdd084c)
    at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_compile.c:4703
#1  0x081d2f6c in zendparse () at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_language_parser.c:4411
#2  0x081d6313 in compile_string (source_string=0xbfdd1a30, filename=0x834a4dc "Command line code") at Zend/zend_language_scanner.l:505
#3  0x081ffdf8 in zend_eval_string (str=0xbfdd397a "$_GET[\"user_id\"] = \"0\"; $user_id = $_GET[\"user_id\"] ?: \"anonymous\";",
    retval_ptr=0x0, string_name=0x834a4dc "Command line code")
    at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_execute_API.c:1097
#4  0x08200011 in zend_eval_string_ex (str=0xbfdd397a "$_GET[\"user_id\"] = \"0\"; $user_id = $_GET[\"user_id\"] ?: \"anonymous\";",
    retval_ptr=0x0, string_name=0x834a4dc "Command line code", handle_exceptions=1)
    at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_execute_API.c:1147
#5  0x08293ecc in main (argc=3, argv=0xbfdd1de4) at $HOME/php-5.3-dev/work/php5.3-200808250230/sapi/cli/php_cli.c:1169

(gdb) c
Continuing.

Breakpoint 2, ZEND_JMP_SET_SPEC_VAR_HANDLER (execute_data=0xb7d83048)
    at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_vm_execute.h:9022
9022            if (i_zend_is_true(value)) {

(gdb) bt
#0  ZEND_JMP_SET_SPEC_VAR_HANDLER (execute_data=0xb7d83048)
    at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_vm_execute.h:9022
#1  0x08235a49 in execute (op_array=0xb7dfaa10) at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_vm_execute.h:104
#2  0x081ffe56 in zend_eval_string (str=0xbfdd397a "$_GET[\"user_id\"] = \"0\"; $user_id = $_GET[\"user_id\"] ?: \"anonymous\";",
    retval_ptr=0x0, string_name=0x834a4dc "Command line code")
    at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_execute_API.c:1112
#3  0x08200011 in zend_eval_string_ex (str=0xbfdd397a "$_GET[\"user_id\"] = \"0\"; $user_id = $_GET[\"user_id\"] ?: \"anonymous\";",
    retval_ptr=0x0, string_name=0x834a4dc "Command line code", handle_exceptions=1)
    at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_execute_API.c:1147
#4  0x08293ecc in main (argc=3, argv=0xbfdd1de4) at $HOME/php-5.3-dev/work/php5.3-200808250230/sapi/cli/php_cli.c:1169

(gdb) c
Continuing.

Program exited normally.

ちゃんと、それぞれ設定した箇所で止まってる。


次に分かったのは「s(step)number」を実行する事で指定した数だけステップイン実行できるようです。
先日、何度エンター・キーを打ったかを確認してみると。。。

(gdb) r -r '$_GET["user_id"] = "0"; $user_id = $_GET["user_id"] ?: "anonymous";'
Starting program: $HOME/php-5.3-dev/php-cli -r '$_GET["user_id"] = "0"; $user_id = $_GET["user_id"] ?: "anonymous";'
Failed to read a valid object file image from memory.

Breakpoint 1, zend_do_jmp_set (value=0xbfbe6e34, jmp_token=0xbfbe6e48, colon_token=0xbfbe6e5c)
    at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_compile.c:4703
4703            opline->opcode = ZEND_JMP_SET;

(gdb) s 1974
210     }
(gdb) s 1

Breakpoint 2, ZEND_JMP_SET_SPEC_VAR_HANDLER (execute_data=0xb7d53048)
    at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_vm_execute.h:9022
9022            if (i_zend_is_true(value)) {
(gdb) c
Continuing.

Program exited normally.
(gdb) q

%

なる程。。。約2000回くらいは押していた訳ですね。桁が違う。_| ̄|○
最初に大きな数値を指定して、徐々に数値を小さくする等して確認しました。


最初に設定したブレーク・ポイントから約2000回くらいステップイン実行する事で、次に設定したブレーク・ポイントへ辿りつくのか。。。内部的には色んな処理が実行されている事が、この事からでも充分に分かります。興味深い。
ブレーク・ポイントを複数設定する事で、その間に何回ステップイン実行されたかが分かると嬉しいけど。。。そんな機能は無さげです。
分かっても(そんなに)有益ではないって事かしら。。。でも、実行回数が少なくなる分だけ早くなりそうな気もするけど。。。うーん。ここでは深く考えないようにしよう。
ちなみに、数値を指定できるのは「n(next)」も同様みたいです。「n(next)387」で同じ位置に辿りつきました。


今日はここまで。そんなに時間が取れなかったので、軽めに。。。という事で。
次回は(今回やろうと思っていた)変数の変更(改竄)あたりを重点的に勉強してみたい。