見出し画像

vdebugの使い方と、さらなるxdebugの使い方


defaultのkeyバインド

大体必要なので覚えといてください。

ステップ実行の用語について

この辺の用語もvdebugに限らず共通語みたいなもんなんで、覚えといて。

で、これはどういう事かをよくわかるスニペットを出してもらった。実行環境は前の記事

とか

とかを参考にセットアップくださいよ〜。なお、ここではdockerを使っとる。

今一度ステップ実行を観察する(chatgptが出力してきたスニペットで)

<?php
// デバッグログファイルのパス
$logFile = 'debug.log';

// ログ関数
function debugLog($message) {
    global $logFile;
    file_put_contents($logFile, date('Y-m-d H:i:s') . ' - ' . $message . PHP_EOL, FILE_APPEND);
}

// デバッグ対象の関数
function exampleFunction($a, $b) {
    debugLog("Entering exampleFunction with arguments: a=$a, b=$b");
    $result = $a + $b;
    debugLog("Calculated result: $result");
    return $result;
}

// メイン処理
$a = 5;
$b = 10;
debugLog("Starting main process with values: a=$a, b=$b");
$result = exampleFunction($a, $b);
debugLog("Final result: $result");

まあ適当な関数を作ってログっていくような奴だね

step overしてみる

としといてconnectionを待機すると

ここで停止する。その後F2でstep overする

さらにF2でsteo overする


終了。左下に変数がごちゃっと出ている。そして書かれたログは

public/debug.log 

2024-06-10 04:32:14 - Starting main process with values: a=5, b=10
2024-06-10 04:32:14 - Entering exampleFunction with arguments: a=5, b=10
2024-06-10 04:32:14 - Calculated result: 15
2024-06-10 04:32:14 - Final result: 15

このようにstep overは関数を一気に跨いでいく時に使う

step intoしてみる

なんとなく想像つきそうだけど、まず待機してbreakpointまで持っていく


ここでStep Intoする、つまりF3だね


するとdebugLog() 関数の中に入っていく

何回かF3を押して関数をなめまわして戻ってくる

この時点でのログは

2024-06-10 04:56:15 - Starting main process with values: a=5, b=10

などなっておりさらにF3を押してすすめるとじゃんじゃんすすんでいく。

ここで重要なのはログを書きこむ作業を1行ずつ確認できるということで、これはstep overと異なるところだ。step intoは関数の中までじっくり見ていくので、より詳細な情報が欲しい場合はこれで行う。

step out

これはStep Intoで入った関数を強制的に抜けるときに使ってみて(手抜き)

その他のxdebugの使い方

<plaintext>
<?php

function func1() {
    sleep(1); // 1秒待つ
    return "Fast function complete!\n";
}

function func2() {
    sleep(3); // 3秒待つ
    return "Slow function complete!\n";
}

function func3() {
    sleep(2); // 2秒待つ
    return "Medium function complete!\n";
}

function execute() {
    echo func1();
    echo func2();
    echo func3();
}

execute();

このexecute() という関数が何かおせえんだけど、どの関数が遅いのかよくわからんなーという場合があるじゃないすか。もちろんここではログを出してるのでfunc1() func2() func3() どれが一番遅いのかすぐわかるんだけどさ。

これをxdebugを使ってprofileしてみる。なお設定は前回のdockerを用いた例を使っているから一応そこは勘弁してほしい

zend_extension=xdebug.so

[xdebug]
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003

この設定を

zend_extension=xdebug.so

[xdebug]
;xdebug.mode=debug
xdebug.mode=debug,profile
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.output_dir=/var/www/html/profiler_output

とかにして、profiler_outputディレクトリ を作ってサーバーが書き込める設定にしておく

すると profiler_output/cachegrind.out.9 的なファイルが生成されているから、それを眺めてみると

version: 1
creator: xdebug 3.3.2 (PHP 8.3.8)
cmd: /var/www/html/public/test.php
part: 1
positions: line

events: Time_(10ns) Memory_(bytes)

fl=(1) php:internal
fn=(1) php::sleep
5 100011646 0

fl=(2) /var/www/html/public/test.php
fn=(2) func1
4 2035 32
cfl=(1)
cfn=(1)
calls=1 0 0
5 100011646 0

fl=(1)
fn=(1)
10 300011360 0

fl=(2)
fn=(3) func2
9 1687 32
cfl=(1)
cfn=(1)
calls=1 0 0
10 300011360 0

fl=(1)
fn=(1)
15 200011776 0

fl=(2)
fn=(4) func3
14 1718 32
cfl=(1)
cfn=(1)
calls=1 0 0
15 200011776 0

fl=(2)
fn=(5) execute
19 3988 0
cfl=(2)
cfn=(2)
calls=1 0 0
20 100013681 32
cfl=(2)
cfn=(3)
calls=1 0 0
21 300013047 32
cfl=(2)
cfn=(4)
calls=1 0 0
22 200013494 32

fl=(2)
fn=(6) {main}
1 1173 48
cfl=(2)
cfn=(5)
calls=1 0 0
25 600044211 96

summary: 600061732 572752

これは人に見辛いのでwebgrindを使う。これまたdockerで起動する。ポートを新たに使うので必要に応じてport貫通の処理を行う事。

webgrind

まあ要するにxdebugのprofileデータparserみたいなもんだな。ここではdockerイメージを使う

wodby/webgrind

色々あるんですが今回はarm64対応のこれにした。いずれにせよこんな感じで起動する

docker run -d -p 8080:8080 -v $(pwd)/profiler_output:/tmp wodby/webgrind

これはとりあえず内部のコンテナport8080で起動しているのを自分ホストにbindしてるのと、hostの profile_output  /tmp にmountしている。この辺はドキュメントに従ってやるとよい

まあこれは環境変数だけど

アクセスしてみると…

うまいこといってれば


こんな画面になり、右側に解析対象ファイルが見える。いくつか見える事もあるけど今回はid:9なのでそれを見てみよう。

そうすると

このようにサマリーがみえる。クリックで開閉するんだけど何か連打すると増えるなwバグかも。ま、いずれにせよ


こうなってるわけ、で、ここでもう一度先のsnippetを見れば

<?php

function func1() {
    sleep(1); // 1秒待つ
    return "Fast function complete!\n";
}

function func2() {
    sleep(3); // 3秒待つ
    return "Slow function complete!\n";
}

function func3() {
    sleep(2); // 2秒待つ
    return "Medium function complete!\n";
}

function execute() {
    echo func1();
    echo func2();
    echo func3();
}

execute();

解析のサマリーをchatgptに解説してもらおう


まあそういう事

graph

これ便利なんで使ってみてね


まとめ

ま、どうしてもこの手の解説記事だと実戦の詳細な情報を出すわけにはいかなくてダミーのsnippetくらいしか出ないけどある程度経験ある人はこれを基に展開する事は十分に可能だと思います、逆に言えばそれが経験値ってことだよね。では。

この記事が気に入ったらサポートをしてみませんか?