概要
軽く触ってみたので gdb を使い方をメモしておきます
環境
- macOS 26.6.2
- gdb
ツールのインストール
- apt -y update
- apt -y install python3 gdb net-tools vim iproute2 lsof
プロセス確認
-
ss -ltnp 'sport = :80'
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("apache2",pid=1,fd=3))
-
lsof -nP -iTCP:80 -sTCP:LISTEN
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
apache2 1 root 3u IPv4 5336 0t0 TCP *:80 (LISTEN)
- ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.7 194460 30372 ? ts 03:11 0:00 apache2 -DFOREGROUND
www-data 19 0.0 0.4 194540 17172 ? S 03:11 0:00 apache2 -DFOREGROUND
www-data 20 0.0 0.4 194540 16400 ? S 03:11 0:00 apache2 -DFOREGROUND
www-data 21 0.0 0.4 194548 16472 ? S 03:11 0:00 apache2 -DFOREGROUND
www-data 22 0.0 0.4 194532 16648 ? S 03:11 0:00 apache2 -DFOREGROUND
www-data 23 0.0 0.4 194532 16648 ? S 03:11 0:00 apache2 -DFOREGROUND
root 62 0.0 0.0 4176 3536 pts/0 Ss 03:46 0:00 /bin/bash
www-data 648 0.0 0.2 194492 11388 ? S 04:23 0:00 apache2 -DFOREGROUND
root 1095 0.1 1.7 684188 68600 pts/0 Sl+ 04:49 0:00 gdb -q -p 1
root 1106 0.0 0.0 4176 3492 pts/1 Ss 04:57 0:00 /bin/bash
root 1117 66.6 0.0 6016 3284 pts/1 R+ 05:02 0:00 ps aux
gdb 起動
- gdb -q -p 19
gdb 観察
php_session_reset_id は今回のアップロード処理ではコールされてなかったことを示すログです
(gdb) info functions php_session_reset_id
All functions matching regular expression "php_session_reset_id":
Non-debugging symbols:
0x0000ffffb5a19310 php_session_reset_id@plt
0x0000ffffb5c92104 php_session_reset_id
(gdb) break php_session_reset_id
Breakpoint 1 at 0xffffb5c92108
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000ffffb5c92108 <php_session_reset_id+4>
(gdb) continue
Continuing.
[Inferior 1 (process 1120) exited normally]
次に php_handler を観測します
php_handler はアップロード処理で libphp.so を使ってコールされたのでブレークポイントで停止します
(gdb) break php_handler
Breakpoint 1 at 0xffffb5f004c8
(gdb) continue
Continuing.
Breakpoint 1, 0x0000ffffb5f004c8 in php_handler () from /usr/lib/apache2/modules/libphp.so
(gdb) bt
#0 0x0000ffffb5f004c8 in php_handler () from /usr/lib/apache2/modules/libphp.so
#1 0x0000aaaaea10d474 in ap_run_handler ()
#2 0x0000aaaaea10dbf4 [PAC] in ap_invoke_handler ()
#3 0x0000aaaaea12777c [PAC] in ap_process_async_request ()
#4 0x0000aaaaea127938 [PAC] in ap_process_request ()
#5 0x0000aaaaea12380c [PAC] in ?? ()
#6 0x0000aaaaea117834 [PAC] in ap_run_process_connection ()
#7 0x0000ffffb6bf43c0 [PAC] in ?? () from /usr/lib/apache2/modules/mod_mpm_prefork.so
#8 0x0000ffffb6bf476c [PAC] in ?? () from /usr/lib/apache2/modules/mod_mpm_prefork.so
#9 0x0000ffffb6bf4e6c [PAC] in ?? () from /usr/lib/apache2/modules/mod_mpm_prefork.so
#10 0x0000aaaaea0eb498 [PAC] in ap_run_mpm ()
#11 0x0000aaaaea0e20bc [PAC] in main ()~
流れの詳細は以下の通りです
- #0 php_handler() PHP モジュールのリクエスト処理。今回のブレークポイント
- #1 ap_run_handler() Apache のハンドラーフックを実行
- #2 ap_invoke_handler() リクエストに対応するハンドラーを呼び出す
- #3 ap_process_async_request() Apache のリクエスト処理本体
- #4 ap_process_request() HTTP リクエスト処理の入口の一つ
- #5 ?? シンボル名を GDB が特定できていない
- #6 ap_run_process_connection() 接続処理のフックを実行
- #7〜#9 mod_mpm_prefork.so 内の関数 prefork MPM による接続・子プロセスの処理
- #10 ap_run_mpm() Apache の MPM 実行処理
- #11 main() Apache のエントリーポイント
さらに関数が現在どの位置にいるか確認します
php_handler の関数の開始位置は 0xffffb5f004c4 であることがわかります
さらに $pc (プログラムカウンタ) を参照します
すると 0xffffb5f004c8 を指しており先程の 0xffffb5f004c4 から4バイト進んでいます
これは adrp (ARM64) の1命令が通常4バイトなので関数の先頭にある1命令分を進んだ位置であることを表しています
(gdb) info address php_handler
Symbol "php_handler" is at 0xffffb5f004c4 in a file compiled without debugging.
(gdb) x/i $pc
=> 0xffffb5f004c8 <php_handler+4>: adrp x1, 0xffffb6ace000 <ini_entries+208>
(gdb) p/x $pc
$1 = 0xffffb5f004c8
関数内で使用されている変数を確認するには args を参照します
php_handler 内では変数は使われていませんでした
(gdb) info args
No symbol table info available.
(gdb) gdb locals
Undefined command: "gdb". Try "help".
(gdb) info locals
No symbol table info available.
(gdb) info frame
Stack level 0, frame at 0xffffca360170:
pc = 0xffffb5f004c8 in php_handler; saved pc = 0xaaaaea10d474
called by frame at 0xffffca3601a0
Arglist at 0xffffca360150, args:
Locals at 0xffffca360150, Previous frame's sp is 0xffffca360170
Saved registers:
x29 at 0xffffca360150, x30 at 0xffffca360158
終了する場合は quit です
その他
gdb には他にもたくさんのコマンドがあります
- info proc exe
- info sharedlibrary
最後に
AI 先生に教えてもらえば覚える必要はないですが理解するとなるとやはり自分の手で実行したほうが良いと実感します