MIRACLE
メールサービス申込 ユーザー登録 パートナー情報
お問い合わせ FAQ サイトマップ
MIRACLE LINUXの特長 製品紹介 サービス案内 購入 サポート 技術フォーラム

プロフィール

吉岡 弘隆 - よしおか ひろたか

日本OSS推進フォーラム ステアリングコミッティ委員
OSDL Board of Directorsを歴任
カーネル読書会主宰

2000年6月、ミラクル・リナックスの創業に参加。
95年~98年、米国OracleにてOracle RDBMSの開発をおこなっていた。
98年にNetscapeのソースコード公開(Mozilla)に衝撃をうけ、オープンソースの世界に飛びこみ、ついには会社も立ち上げてしまう。
2008年6月取締役CTOを退任し一プログラマとなった。

ミラクル関連リンク

なかのひと

サイト検索

2010年8月

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

« hyoshiok 2.0 | メイン | Linux Kernel 2.6.18とCache Pollution Aware Patch »

大規模ソフトウェアをgdbを利用して微視的視点から理解をする

たまたま講読している php-dev というPHPの実装を日本語で議論するメーリングリストで「mbstring の新関数」というスレッドがあった。新規にmb_list_encodings_alias_names()という関数を追加したらしいのだが、既存のmb_list_encodings()とどう違うのかどうかという議論がわきおこっている。

ここでは、mb_list_encodings()を題材にどうやってphpの実装を理解していくか、そのプロセスを記述してみたい。もちろんこの方法がベストであるとか、この方法でなければいけないとか、いつでもこの方法が適用可能だなんてことを主張するつもりは一切ないが、一つの例として大規模ソフトウェアの微視的理解方法を理解いただきたい。

1) mb_list_encodingsがどこで利用されているかを知る。

$ cd /usr/src/php-5.1.4
$ time find -type f|xargs egrep -l mb_list_encodings_alias_names

real    0m21.909s
user    0m0.088s
sys    0m0.606s

新規に追加された関数mb_list_encodings_alias_names()は現在のバージョンでは利用されていない。(あたりまえだ)

$ time find -type f|xargs egrep -l mb_list_encodings
./ext/mbstring/mbstring.c
./ext/mbstring/mbstring.h
./ext/mbstring/.libs/mbstring.o
./sapi/cli/php
./libs/libphp5.so
./.libs/libphp5.so

real    0m0.450s
user    0m0.180s
sys    0m0.248s

既存のmb_list_encodingsは、mbstring.{c|h}で利用されている。。*.oとかもgrepでひっかかる。実行時間が最初は21.909秒、今回は0.450秒で激減しているのは、ページキャッシュに当該ファイルが載ってしまったためと考えられる。

2) ソースファイルを読む。mbstring.c

/* {{{ proto array mb_list_encodings()
   Returns an array of all supported encodings */
PHP_FUNCTION(mb_list_encodings)
{
    const mbfl_encoding **encodings;
    const mbfl_encoding *encoding;
    int i;

    array_init(return_value);
    i = 0;
    encodings = mbfl_get_supported_encodings();
    while ((encoding = encodings[i++]) != NULL) {
        add_next_index_string(return_value, (char *) encoding->name, 1);
    }
}

3) 実行してみる。

$ php -r ' print_r(mb_list_encodings());'
Array
(
    [0] => pass
    [1] => auto
    [2] => wchar
    [3] => byte2be
    [4] => byte2le
    [5] => byte4be
    [6] => byte4le
    [7] => BASE64
    [8] => UUENCODE
    [9] => HTML-ENTITIES
    [10] => Quoted-Printable
    [11] => 7bit
    [12] => 8bit
...
)

4) デバッガで実行する。

ブレークポイントをどこに設定するか?

当該ソースコードは
PHP_FUNCTION(mb_list_encodings)
となっていて、PHP_FUNCTION()というマクロを利用してmb_list_encodings()を定義している。PHP_FUNCTIONの定義を丹念におっていけば、どのように展開されていくかが分るのだが、もっと直接的な方法でしる。

先のfind |xargs egrepというイディオムで当該関数を含んだファイル一覧が得られたが、いくつかのバイナリファイルにも含まれていることがわかる。そこで力づくで

$ strings ./sapi/cli/php|egrep mb_list_encodings
zif_mb_list_encodings
mb_list_encodings

とするとzif_mb_list_encodings()がどうも当該関数名だということがわかる。

(gdb) b main
Breakpoint 1 at 0x82824e0: file /usr/src/php-5.1.4/sapi/cli/php_cli.c, line 581.

取り合えづmainにブレークポイントを設定した。

(gdb) b mb_list_encodings
Function "mb_list_encodings" not defined.
Make breakpoint pending on future shared library load? (y or [n])

予想どおりmb_list_encodingsという関数はない。

(gdb) b zif_mb_list_encodings

Breakpoint 2 at 0x8102931: file /usr/src/php-5.1.4/ext/mbstring/mbstring.c, line 2327.

ビンゴである。

実行する。

(gdb) run -r ' print_r(mb_list_encodings());'
Starting program: /usr/local/bin/php -r ' print_r(mb_list_encodings());'
[Thread debugging using libthread_db enabled]
[New Thread -1208068416 (LWP 4872)]
[Switching to Thread -1208068416 (LWP 4872)]

Breakpoint 1, main (argc=3, argv=0xbfe1e994)
    at /usr/src/php-5.1.4/sapi/cli/php_cli.c:581

(gdb) c
Continuing.

Breakpoint 2, zif_mb_list_encodings (ht=0, return_value=0xbfe1e580,
    return_value_ptr=0x0, this_ptr=0x0, return_value_used=1)
    at /usr/src/php-5.1.4/ext/mbstring/mbstring.c:2327

当該ブレークポイントで停止した。

スタックフレームを見ると呼び出し系列が一目瞭然でわかる。

(gdb) bt
#0  zif_mb_list_encodings (ht=0, return_value=0xbfe1e580,
    return_value_ptr=0x0, this_ptr=0x0, return_value_used=1)
    at /usr/src/php-5.1.4/ext/mbstring/mbstring.c:2327
#1  0x082222a8 in zend_do_fcall_common_helper_SPEC (execute_data=0xbfe1e580)
    at /usr/src/php-5.1.4/Zend/zend_vm_execute.h:200
#2  0x08221c8d in execute (op_array=0x950635c)
    at /usr/src/php-5.1.4/Zend/zend_vm_execute.h:92
#3  0x0820057c in zend_eval_string (str=0x950635c "\004", retval_ptr=0x0,
    string_name=0x841e72f "Command line code")
    at /usr/src/php-5.1.4/Zend/zend_execute_API.c:1116
#4  0x082006c8 in zend_eval_string_ex (
    str=0xbff0f932 " print_r(mb_list_encodings());", retval_ptr=0x0,
    string_name=0x841e72f "Command line code", handle_exceptions=1)
    at /usr/src/php-5.1.4/Zend/zend_execute_API.c:1150
#5  0x082831b2 in main (argc=3, argv=0xbfe1e994)
    at /usr/src/php-5.1.4/sapi/cli/php_cli.c:1181

10_1 あとはステップ実行なりなんなりして微視的な理解を深めるだけである。

ここまでに到達するのに30分とかからない。

トラックバック

このページのトラックバックURL:
http://www.typepad.jp/t/trackback/4447/6546189

このページへのトラックバック一覧 大規模ソフトウェアをgdbを利用して微視的視点から理解をする:

» [その他技術]gdbを使ってコードを読む トラックバック Do You PHP はてな
ここでは、mb_list_encodings()を題材にどうやってphpの実装を理解していくか、そのプロセスを記述してみたい。もちろんこの方法がベストであるとか、この方法でなければいけないとか、いつでもこの方法が適用可能だなんてことを主張するつもりは一切ないが、一つの例として... [続きを読む]

» [考察] ソースがあるからこそこういうことが可能 トラックバック ます’s Diary - どうでもいい事100選
この件について真面目に考えています。満ち干でさんは、どういう意図があって投稿したのだろうか。 や。別に怒っている訳では全くありませんので。あまり賢くない頭をフル回転させながら考え中。 単に「貴方達は恵まれてるのですよ」という事なのだろうか。 確かに、昔に比... [続きを読む]

» [PHP] define定義を無効にする トラックバック ます’s Diary - どうでもいい事100選
C言語には「undef」という命令があって「define」した内容を無効にする事ができます。 PHPにも同じ名前で「define」が存在しますが「undef」に相当する命令が見当たりませんでした。 知っている方は是非とも教えて頂きたいと思います。これからやろうとしている事が盛大に無... [続きを読む]

» ソースコードの読み方 トラックバック ユメのチカラ
ソフトウェア工学の標準的なカリキュラムにソースコードの読み方というのがあるのかな [続きを読む]

» ソースコードの読み方 トラックバック 未来のいつか/hyoshiokの日記
今朝、会社のブログ(ユメのチカラ)にソースコードの読み方というエントリを書いたのだが、凄い勢いでブックマークされている。自分の日記、ブログで初の100ブックマーク越となる。(ぱちぱちぱち) http://b.hatena.ne.jp/entry/http://blog.miraclelinux.com/yume/2007/08/po... [続きを読む]

» デバッグ方法論 トラックバック ユメのチカラ
実践的なデバッグ方法論(デバッグの仕方、事例研究)も強く求められている。デバッガ [続きを読む]

コメント

う。恥を晒してしまってすみません。
自分もまだまだ若いので、議論するつもりもないので適当に流していますが。
実行部隊が全然居ないのが一番の問題な訳だし。議論したところで誰が作業すんだよ、みたいな。
若いうちは、色んな事を経験しろ、という事ですかね。どうでもいい事、失礼しました。
ともあれ、gdbの件はいつも参考になります。
有粋な情報、ありがとうございました。

ますさん、コメントありがとうございます。

コードの読み方、gdbの使い方を性凝りもなく、ご紹介しているのは、少しでも多くの人にコードを読むことに馴染んでもらおうと思っているからです。

それがひいてはコードを書く人を発掘することにつながるのではないかと思っています。時間はかかりますが、いつの日かそのような人が現れてくれればと思います。

「ソースがあるからこそこういうことが可能」という前提が分かっている人と分かってない人の間のギャップが大きすぎると感じている今日この頃でございます(何

満ち干でさん、コメントありがとうございます。

「ソースがあるからこそこういうことが可能」ということは地道に伝えていかないといけないと思っています。

一つ一つ事例を積み重ねて、時間はかかりますけど、伝えていこうと思います。

コメントを投稿

会社情報 採用情報 個人情報保護方針 商標等取り扱い事項 English
Copyright(c)2000-2006 MIRACLE LINUX CORPORATION. All Rights Reserved.