2026年10月29日木曜日

gdb の使い方メモ

gdb の使い方メモ

概要

軽く触ってみたので 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 先生に教えてもらえば覚える必要はないですが理解するとなるとやはり自分の手で実行したほうが良いと実感します

0 件のコメント:

コメントを投稿