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

どうでもいい記事100選

「?:」演算子(続き)

先日のですが。
最後はprintfを盛大に仕込むという荒業で乗り切ったものの、今後も同じ作業を行い続けるのは効率が悪すぎるので、gdbを使って効率よく作業できないか。。。と探っていたところ、できるようです。しかも簡単に。_| ̄|○

とりあえず、前準備としてPHPバイナリを用意(--enable-debugオプション付きでビルド)。

% cd $HOME
% mkdir ./php-5.3-dev
% mkdir ./php-5.3-dev/work
% cd ./php-5.3-dev/work
% wget http://snaps.php.net/php5.3-200808250230.tar.gz
% gzip -dc ./php5.3-200808250230.tar.gz | tar xvf -
% cd ./php5.3-200808250230
% ./configure --disable-all --enable-debug --with-config-file-path=$HOME/php-5.3-dev
% gmake
% cp ./sapi/cli/php $HOME/php-5.3-dev/php-cli
% cp ./php.ini-recommended $HOME/php-5.3-dev/php.ini
% $HOME/php-5.3-dev/php-cli -v
PHP 5.3.0alpha2-dev (cli) (built: Aug 25 2008 11:57:05) (DEBUG)
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2008 Zend Technologies

前回は「i_zend_is_true」関数の発見以降がグダグダな展開だったので、該当関数をブレーク・ポイントに設定してみます。
gdbを起動してブレーク・ポイントを設定。処理を実行。その後「bt」を実行。

% 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 i_zend_is_true
Breakpoint 1 at 0x823a644: file $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_execute.h, line 82.

(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, i_zend_is_true (op=0xb7de62dc) at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_execute.h:82
82              switch (Z_TYPE_P(op)) {

(gdb) bt
#0  i_zend_is_true (op=0xb7de62dc) at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_execute.h:82
#1  0x0824cf03 in ZEND_JMP_SET_SPEC_VAR_HANDLER (execute_data=0xb7d6f048)
    at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_vm_execute.h:9022
#2  0x08235a49 in execute (op_array=0xb7de6a10) at $HOME/php-5.3-dev/work/php5.3-200808250230/Zend/zend_vm_execute.h:104
#3  0x081ffe56 in zend_eval_string (
    str=0xbfaf2964 "$_GET[\"user_id\"] = \"0\"; $user_id = $_GET[\"user_id\"] ?: \"anonymous\"; var_dump( $user_id );", 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
#4  0x08200011 in zend_eval_string_ex (
    str=0xbfaf2964 "$_GET[\"user_id\"] = \"0\"; $user_id = $_GET[\"user_id\"] ?: \"anonymous\"; var_dump( $user_id );", 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=0xbfaf0ae4) at $HOME/php-5.3-dev/work/php5.3-200808250230/sapi/cli/php_cli.c:1169

速攻で「/zend_vm_execute.h」の「9022」行目から呼ばれている事が判明。。。すげー簡単。_| ̄|○
効率の悪さとgdbを全然使いこなせていないのが露呈(再認識)した瞬間。。。でも、また一つ賢くなれたので、次からは(より)効率よく作業できるぜ。。。と、前向きに考えよう。
相変わらず、亀のような遅さで成長しておりますが。。。めげずに頑張っていこう。


hyoshiokさんのトコでデバッグの手法とデバッガについて手厳しい発言がありますが、グサリと内心をつかれつつも、確かに、この手の内容については具体的に教えてもらった記憶はないんだよなぁ。。。gdb関連の本を読めって事?
gdbの使い方とか事例とか、日本語でどこか一箇所にまとまってると嬉しいですね。。。っていうか、ググれって事なんでしょうけど。_| ̄|○