名 前
ptrace − プ ロ セ ス の ト レ ー ス
書 式
#include <sys/ptrace.h>
long
ptrace(enum __ptrace_request request,
pid_t pid,
void *addr, void *data);
説 明
ptrace() シ ス テ ム コ ー ル は 、 親 プ ロ セ ス が 、 別 の プ ロ セ ス の 実 行 の 監 視 /制 御 を 行 っ た り 、 コ ア イ メ ー ジ (core image) や レ ジ ス タ の 調 査 /変 更 を 行 っ た り す る 手 段 を 提 供 す る 。 ptrace() は 、 主 に ブ レ ー ク ポ イ ン ト に よ る デ バ ッ グ や シ ス テ ム コ ー ル の ト レ ー ス を 実 装 す る の に 用 い ら れ る 。 ト レ ー ス を 開 始 す る に は 、 ま ず 親 プ ロ セ ス で fork(2) を 呼 び 出 す 。 生 成 さ れ た 子 プ ロ セ ス で PTRACE_TRACEME を 行 い 、 続 い て (典 型 的 に は ) exec(3) を 行 な う 。 別 の 方 法 と し て は 、 親 プ ロ セ ス が 既 存 の プ ロ セ ス に 対 し て PTRACE_ATTACH を 使 用 し 、 ト レ ー ス を 開 始 す る 。 ト レ ー ス の 実 行 中 、 子 プ ロ セ ス は シ グ ナ ル が 配 送 さ れ る た び に 、 た と え そ の シ グ ナ ル が 無 視 す べ き も の で あ っ て も 停 止 す る (SIGKILL は 例 外 で 、 通 常 ど お り の 効 果 を も た ら す )。 親 プ ロ セ ス に は 次 の wait(2) で 通 知 さ れ 、 停 止 し て い る 間 に 子 プ ロ セ ス を 調 べ た り 修 正 し た り す る こ と が で き る 。 そ し て 親 プ ロ セ ス は 子 プ ロ セ ス の 実 行 を 再 開 さ せ る が 、 配 送 さ れ た シ グ ナ ル を 無 視 す る こ と も で き る (あ る い は 代 わ り に 別 の シ グ ナ ル を 配 送 す る こ と も で き る ) 。 親 プ ロ セ ス が ト レ ー ス を 終 了 す る 際 に は 、 PTRACE_KILL を 使 用 し て 子 プ ロ セ ス を 終 了 さ せ る こ と も で き る し 、 PTRACE_DETACH を 用 い て 通 常 の ト レ ー ス な し の モ ー ド に し て 、 実 行 を 継 続 さ せ る こ と も で き る 。
request
の 値 が こ の シ
ス テ ム コ ー ル
の 動 作 を 決 定
す る :
PTRACE_TRACEME こ の プ ロ
セ ス が 親 プ ロ
セ ス に よ っ て
ト レ ー ス さ れ
る こ と を 表 す
。 こ の プ ロ セ
ス に (SIGKILL 以 外 の
) シ グ ナ ル が 配
送 さ れ る と 、
プ ロ セ ス は 停
止 し 、 親 プ ロ
セ ス に wait(2) を 通
じ て 通 知 さ れ
る 。 ま た 、 こ
れ 以 降 は こ の
プ ロ セ ス が
execve(2) を 呼 び 出
す 度 に SIGTRAP が 送
信 さ れ る よ う
に な る 。 こ れ
に よ っ て 、 親
プ ロ セ ス は 新
し い プ ロ グ ラ
ム が 実 行 を 開
始 す る 前 に 制
御 す る こ と が
で き る 。 親 プ
ロ セ ス が 自 プ
ロ セ ス を ト レ
ー ス す る つ も
り が な い 場 合
に は 、 お そ ら
く こ の プ ロ セ
ス は 本 要 求 を
行 う べ き で は
な い だ ろ う 。
(pid, addr, data は 無
視 さ れ る 。 ) 上
記 の 要 求 は 子
プ ロ セ ス だ け
が 行 な う も の
で あ る 。 残 り
は 親 プ ロ セ ス
だ け が 行 な う
も の で あ る 。
以 下 の 要 求 で
は 、 pid で 操 作
の 対 象 と な る
子 プ ロ セ ス を
指 定 す る 。
PTRACE_KILL を 除 き 、
要 求 を 行 な う
た め に は 子 プ
ロ セ ス は 停 止
し て い な け れ
ば な ら な い 。
PTRACE_PEEKTEXT, PTRACE_PEEKDATA 子
プ ロ セ ス の メ
モ リ の addr の 位
置 か ら 1 ワ ー ド
を 読 み 出 す 。
読 み 出 し た ワ
ー ド は ptrace() の 返
り 値 と し て 返
さ れ る 。 Linux で は
テ キ ス ト (text) と デ
ー タ (data) で 同 じ ア
ド レ ス 空 間 を
使 用 す る た め
、 こ の 2 つ の 要
求 は 現 在 の と
こ ろ 同 じ も の
で あ る 。 (引 き
数 data は 無 視 さ
れ る 。 )
PTRACE_PEEKUSER 子 プ ロ セ
ス の USER 領 域 の オ
フ セ ッ ト addr の
位 置 か ら 1 ワ ー
ド を 読 み 込 む
。 USER 領 域 に は そ
の プ ロ セ ス の
レ ジ ス タ (registers) な
ど の 情 報 が 保
持 さ れ て い る
(<sys/user.h> を 参 照
)。 読 み 込 ん だ
ワ ー ド は ptrace() コ
ー ル の 結 果 と
し て 返 さ れ る
。 た い て い は
オ フ セ ッ ト は
ワ ー ド 境 界 に
な け れ ば な ら
な い が 、 ア ー
キ テ ク チ ャ に
よ っ て は そ の
必 要 は な い 。
「 注 意 」 の 節
を 参 照 。 (data は
無 視 さ れ る 。 )
PTRACE_POKETEXT, PTRACE_POKEDATA ワ
ー ド data を 子 プ
ロ セ ス の メ モ
リ の addr の 位 置
へ コ ピ ー す る
。 上 と 同 様 に
、 現 在 の と こ
ろ 二 つ の 要 求
は 同 じ も の で
あ る 。
PTRACE_POKEUSER ワ ー ド data
を 子 プ ロ セ ス
の USER 領 域 の オ フ
セ ッ ト addr の 位
置 に コ ピ ー す
る 。 上 と 同 様
に 、 通 常 、 オ
フ セ ッ ト は ワ
ー ド 境 界 に な
け れ ば な ら な
い 。 カ ー ネ ル
の 完 全 性 (integrity) を
維 持 す る た め
、 変 更 内 容 に
よ っ て は USER 領 域
の 変 更 は 禁 止
さ れ て い る 。
PTRACE_GETREGS, PTRACE_GETFPREGS そ
れ ぞ れ 、 子 プ
ロ セ ス の 汎 用
レ ジ ス タ 、 浮
動 小 数 点 レ ジ
ス タ を 親 プ ロ
セ ス の data の 位
置 に コ ピ ー す
る 。 こ の data の 書
式 に 関 し て は
<sys/user.h> を 参 照
す る こ と 。 (addr
は 無 視 さ れ る
。 )
PTRACE_GETSIGINFO (Linux 2.3.99-pre6 以 降 )
停 止 の 原 因 と
な っ た シ グ ナ
ル に 関 す る 情
報 を 取 得 す る
。 siginfo_t 構 造 体
(sigaction(2) 参 照 ) を 子
プ ロ セ ス か ら
親 プ ロ セ ス の
data の 位 置 に コ
ピ ー す る 。 (addr
は 無 視 さ れ る
。 )
PTRACE_SETREGS, PTRACE_SETFPREGS そ
れ ぞ れ 、 子 プ
ロ セ ス の 汎 用
レ ジ ス タ 、 浮
動 小 数 点 レ ジ
ス タ に 親 プ ロ
セ ス の date の 位
置 か ら コ ピ ー
す る 。 PTRACE_POKEUSER と
同 様 に 、 汎 用
レ ジ ス タ に よ
っ て は 変 更 が
禁 止 さ れ て い
る 場 合 が あ る
。 (addr は 無 視 さ
れ る 。 )
PTRACE_SETSIGINFO (Linux 2.3.99-pre6 以 降 )
シ グ ナ ル 情 報
を 設 定 す る 。
siginfo_t 構 造 体 を
親 プ ロ セ ス の
デ ー タ data の 位
置 か ら 子 プ ロ
セ ス に コ ピ ー
す る 。 こ の 処
理 を 行 う こ と
が で き る の は
、 子 プ ロ セ ス
に 通 常 は 配 送
さ れ る は ず で
ト レ ー サ に 捕
捉 さ れ た シ グ
ナ ル に つ い て
だ け で あ る 。
こ れ ら の 通 常
の シ グ ナ ル と
ptrace() 自 身 が 発 生
す る シ グ ナ ル
を 見 分 け る の
は 難 し い か も
し れ な い 。 (addr
は 無 視 さ れ る
。 )
PTRACE_SETOPTIONS (Linux 2.4.6 以 降 ;
バ グ の 章 に あ
る 警 告 も 参 照 )
親 プ ロ セ ス の
data に 基 づ い て
ptrace の オ プ シ ョ ン
を 設 定 す る (addr
は 無 視 さ れ る
)。 data は オ プ シ
ョ ン の ビ ッ ト
マ ス ク と し て
解 釈 さ れ 、 オ
プ シ ョ ン に は
以 下 の フ ラ グ
を 指 定 で き る :
PTRACE_O_TRACESYSGOOD
(Linux 2.4.6 以 降 ) シ ス テ
ム コ ー ル の ト
ラ ッ プ が 配 送
さ れ た と き に
、 シ グ ナ ル 番
号 の ビ ッ ト 7 を
設 定 す る (す な
わ ち 、 (SIGTRAP | 0x80) を
配 送 す る )。 こ
れ に よ り 、 ト
レ ー サ が 通 常
の ト ラ ッ プ と
シ ス テ ム コ ー
ル に よ る ト ラ
ッ プ を 区 別 し
や す く な る 。
(PTRACE_O_TRACESYSGOOD は ど の
ア ー キ テ ク チ
ャ で も 動 作 し
な い 可 能 性 が
あ る 。 )
PTRACE_O_TRACEFORK (Linux 2.5.46 以 降 )
次 の fork(2) 呼 び 出
し 時 に SIGTRAP |
PTRACE_EVENT_FORK << 8 で 子
プ ロ セ ス の 動
作 を 停 止 さ せ
、 新 た に fork さ れ
た プ ロ セ ス の
ト レ ー ス を 自
動 的 に 開 始 し
、 SIGSTOP で そ の プ
ロ セ ス の 実 行
を 開 始 す る 。
新 し い プ ロ セ
ス の PID は PTRACE_GETEVENTMSG
で 取 得 で き る
。
PTRACE_O_TRACEVFORK (Linux 2.5.46 以 降 )
次 の vfork(2) 呼 び 出
し 時 に SIGTRAP |
PTRACE_EVENT_VFORK << 8 で
子 プ ロ セ ス の
動 作 を 停 止 さ
せ 、 新 た に vfork さ
れ た プ ロ セ ス
の ト レ ー ス を
自 動 的 に 開 始
し 、 SIGSTOP で そ の
プ ロ セ ス の 実
行 を 開 始 す る
。 新 し い プ ロ
セ ス の PID は
PTRACE_GETEVENTMSG で 取 得
で き る 。
PTRACE_O_TRACECLONE (Linux 2.5.46 以 降 )
次 の clone(2) 呼 び 出
し 時 に SIGTRAP |
PTRACE_EVENT_CLONE << 8 で 子
プ ロ セ ス の 動
作 を 停 止 さ せ
、 新 た に clone で 作
成 さ れ た プ ロ
セ ス の ト レ ー
ス を 自 動 的 に
開 始 し 、 SIGSTOP で
プ ロ セ ス の 実
行 を 開 始 す る
。 新 し い プ ロ
セ ス の PID は
PTRACE_GETEVENTMSG で 取 得
で き る 。 こ の
オ プ シ ョ ン で
全 て の clone(2) コ ー
ル を 捕 ま え ら
れ る わ け で は
な い 。 子 プ ロ
セ ス が CLONE_VFORK フ
ラ グ 付 き で clone(2)
を 呼 び 出 し た
場 合 、 PTRACE_O_TRACEVFORK
が 設 定 さ れ て
い れ ば 代 わ り
に PTRACE_EVENT_VFORK が 配
送 さ れ る 。 ま
た 、 子 プ ロ セ
ス が 終 了 シ グ
ナ ル を SIGCHLD に 設
定 し て clone(2) を 呼
び 出 し た 場 合
は 、 PTRACE_O_TRACEFORK が
設 定 さ れ て い
れ ば PTRACE_EVENT_FORK が 配
送 さ れ る 。
PTRACE_O_TRACEEXEC (Linux 2.5.46 以 降 )
次 の execve(2) 呼 び
出 し 時 に SIGTRAP |
PTRACE_EVENT_EXEC << 8 で 子
プ ロ セ ス の 動
作 を 停 止 さ せ
る 。
PTRACE_O_TRACEVFORKDONE (Linux 2.5.60 以 降
) 次 の vfork(2) 呼 び
出 し 時 に SIGTRAP |
PTRACE_EVENT_VFORK_DONE << 8 で
子 プ ロ セ ス の
動 作 を 停 止 さ
せ る 。
PTRACE_O_TRACEEXIT (Linux 2.5.60 以 降 )
終 了 (exit) 時 に SIGTRAP |
PTRACE_EVENT_EXIT << 8 で 子
プ ロ セ ス の 動
作 を 停 止 さ せ
る 。 子 プ ロ セ
ス の 終 了 ス テ
ー タ ス は
PTRACE_GETEVENTMSG で 取 得
で き る 。 こ の
停 止 は レ ジ ス
タ が ま だ 参 照
可 能 で あ る プ
ロ セ ス 終 了 処
理 の 初 期 に 行
わ れ 、 ト レ ー
サ は ど こ で 終
了 が 発 生 し た
か を 知 る こ と
が で き る 。 通
常 の 終 了 通 知 (exit
notification) は プ ロ セ ス
の 終 了 処 理 が
完 了 し た 後 に
行 わ れ る 。 コ
ン テ キ ス ト を
参 照 す る こ と
は で き る に も
関 わ ら ず 、 ト
レ ー サ は こ の
時 点 か ら 終 了
を 止 め る こ と
は で き な い 。
PTRACE_GETEVENTMSG
(Linux 2.5.46 以 降 ) 発 生 し
た ば か り の ptrace イ
ベ ン ト に 関 す
る メ ッ セ ー ジ
を (unsigned long 型 で ) 取
得 す る 。 取 得
し た メ ッ セ ー
ジ は 親 プ ロ セ
ス の data の 位 置
に 格 納 さ れ る
。 得 ら れ る 内
容 は 、 PTRACE_EVENT_EXIT の
場 合 は 子 プ ロ
セ ス の 終 了 ス
テ ー タ ス で あ
り 、 PTRACE_EVENT_FORK,
PTRACE_EVENT_VFORK, PTRACE_EVENT_CLONE
の 場 合 は 新 し
い プ ロ セ ス の PID
で あ る 。 Linux 2.6.18 以
降 で は 、 新 し
い プ ロ セ ス の PID
は PTRACE_EVENT_VFORK_DONE で 入
手 で き る 。 (addr
は 無 視 さ れ る
。 )
PTRACE_CONT 停 止 し た 子
プ ロ セ ス の 実
行 を 再 開 さ せ
る 。 data が ゼ ロ
で な く 、 SIGSTOP で
も な け れ ば 、
子 プ ロ セ ス に
配 送 さ れ る シ
グ ナ ル と 解 釈
さ れ る 。 ゼ ロ
や SIGSTOP の 場 合 は
シ グ ナ ル は 配
送 さ れ な い 。
こ れ を 使 う と
、 例 え ば 、 親
プ ロ セ ス は 子
プ ロ セ ス に 送
ら れ た シ グ ナ
ル を 実 際 に 配
送 す る か ど う
か を 制 御 す る
こ と が で き る
。 (addr は 無 視 さ
れ る 。 )
PTRACE_SYSCALL, PTRACE_SINGLESTEP
PTRACE_CONT と 同 様 に 停 止 し た 子 プ ロ セ ス を 再 開 す る 。 た だ し 、 PTRACE_SYSCALL の 場 合 は 子 プ ロ セ ス が 次 に シ ス テ ム コ ー ル に 入 る か シ ス テ ム コ ー ル か ら 抜 け る か す る 時 に 、 PTRACE_SINGLESTEP の 場 合 は 1 命 令 (instruction) 実 行 し た 後 に 停 止 さ せ る (通 常 ど お り 、 子 プ ロ セ ス は シ グ ナ ル を 受 け 取 っ た 場 合 に も 停 止 す る )。 親 プ ロ セ ス か ら 見 る と 、 子 プ ロ セ ス は SIGTRAP を 受 信 し て 停 止 し た よ う に 見 え る 。 そ の た め 、 例 え ば PTRACE_SYSCALL を 使 う と 、 1回 目 の 停 止 で 引 き 数 を 調 べ て PTRACE_SYSCALL を 実 行 し 、 2回 目 の 停 止 で シ ス テ ム コ ー ル の 返 り 値 を 調 べ る 、 と い う よ う な こ と が で き る 。 引 き 数 data は PTRACE_CONT の 場 合 と 同 じ 様 に 解 釈 さ れ る 。 (addr は 無 視 さ れ る 。 )
PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP (Linux 2.6.14 以 降 )
PTRACE_SYSEMU は 、 実 行 を 再 開 し 、 次 の シ ス テ ム コ ー ル に 入 る 時 に 停 止 さ せ る 。 シ ス テ ム コ ー ル は 実 行 さ れ な い 。 PTRACE_SYSEMU_SINGLESTEP も 同 様 だ が 、 シ ス テ ム コ ー ル で な い 場 合 に は 1 命 令 (singlestep) だ け 実 行 し た 時 点 で も 停 止 さ せ る 。 こ の コ ー ル は User Mode Linux の よ う に 子 プ ロ セ ス の シ ス テ ム コ ー ル を 全 て エ ミ ュ レ ー ト し よ う と す る プ ロ グ ラ ム で 使 用 さ れ る 。 引 き 数 data は PTRACE_CONT の 場 合 と 同 じ 様 に 解 釈 さ れ る 。 (addr は 無 視 さ れ る 。 全 て の ア ー キ テ ク チ ャ で サ ポ ー ト さ れ て い る わ け で は な い 。 )
PTRACE_KILL 子
プ ロ セ ス に SIGKILL
を 送 り 終 了 さ
せ る 。 (addr と data
は 無 視 さ れ る
。 )
PTRACE_ATTACH
pid で 指 定 さ れ た プ ロ セ ス に 接 続 (attach) し 、 そ れ を 呼 び 出 し 元 の プ ロ セ ス の 子 プ ロ セ ス と し て ト レ ー ス で き る よ う に す る 。 子 プ ロ セ ス は PTRACE_TRACEME し た か の よ う に 振 舞 う 。 呼 び 出 し 元 の プ ロ セ ス は そ の ほ と ん ど の 目 的 に お い て 、 そ の 子 プ ロ セ ス の 実 際 の 親 に な る (例 え ば 、 子 プ ロ セ ス の イ ベ ン ト の 通 知 を 受 け と っ た り 、 ps(1) で 親 と し て 表 示 さ れ た り す る )。 し か し 、 子 プ ロ セ ス で getppid(2) を 実 行 し た 場 合 に は 元 の 親 プ ロ セ ス の PID が 返 さ れ る 。 子 プ ロ セ ス に は SIGSTOP が 送 ら れ る が 、 こ の 呼 び 出 し が 完 了 す る ま で に 必 ず し も 停 止 す る と は 限 ら な い 。 子 プ ロ セ ス の 停 止 を 待 つ に は wait(2) を 使 用 す る こ と 。 (addr と data は 無 視 さ れ る 。 )
PTRACE_DETACH
PTRACE_CONT と 同 様 に 停 止 し た 子 プ ロ セ ス を 再 開 す る 。 た だ し ま ず そ の プ ロ セ ス か ら の 分 離 (detach) を 行 い 、 PTRACE_ATTACH で の 親 の 切 り 換 え に よ る 効 果 と PTRACE_TRACEME の 効 果 を 取 り 消 す 。 意 図 し た も の で は な い だ ろ う が 、 Linux で は 、 ト レ ー ス さ れ て い る 子 プ ロ セ ス は ど の よ う な 方 法 で ト レ ー ス を 開 始 さ れ た と し て も 、 こ の 方 法 で 分 離 (detach) す る こ と が で き る 。 (addr は 無 視 さ れ る 。 )
返 り 値
成 功 す る と 、 PTRACE_PEEK* の 場 合 は 要 求 し た デ ー タ を 返 し 、 そ れ 以 外 の 場 合 は 0 を 返 す 。 エ ラ ー の 場 合 は −1 を 返 し 、 errno が 適 切 に 設 定 さ れ る 。 PTRACE_PEEK* が 成 功 し て 返 す 値 も −1 に な る こ と が あ る た め 、 そ の よ う な 要 求 の 場 合 に は 、 呼 び 出 し 元 は errno を 調 べ 、 エ ラ ー か 発 生 し た の か ど う か を 判 断 し な け れ ば な ら な い 。
エ ラ ー
EBUSY |
(i386 の み ) デ バ ッ グ レ ジ ス タ の 確 保 ま た は 解 放 で エ ラ ー が 発 生 し た 。
親 プ ロ
セ ス ま た は 子
プ ロ セ ス の メ
モ リ の 不 正 な
領 域 に 読 み 書
き し よ う と し
た 。 お そ ら く
そ の 領 域 が マ
ッ ピ ン グ さ れ
て い な い か 、
そ の 領 域 へ の
ア ク セ ス が 許
さ れ て い な い
か で あ る 。 不
運 な こ と に 、 Linux
で は こ の よ う
な エ ラ ー の 場
合 、 多 か れ 少
な か れ 恣 意 的
に EIO を 返 し た
り EFAULT を 返 し た
り す る こ と が
あ る 。 不 正 な オ プ シ ョ ン を 設 定 し よ う と し た 。
|