368 lines
9.5 KiB
Groff
368 lines
9.5 KiB
Groff
.\" %FreeBSD: src/lib/libc/sys/ptrace.2,v 1.36 2004/07/12 04:43:58 marcel Exp %
|
|
.\" %NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
|
|
.\"
|
|
.\" This file is in the public domain.
|
|
.\" $FreeBSD$
|
|
.Dd August 11, 2003
|
|
.Dt PTRACE 2
|
|
.Os
|
|
.Sh 名称
|
|
.Nm ptrace
|
|
.Nd プロセスのトレースとデバッグ
|
|
.Sh ライブラリ
|
|
.Lb libc
|
|
.Sh 書式
|
|
.In sys/types.h
|
|
.In sys/ptrace.h
|
|
.Ft int
|
|
.Fn ptrace "int request" "pid_t pid" "caddr_t addr" "int data"
|
|
.Sh 解説
|
|
.Fn ptrace
|
|
システムコールはトレースとデバッグの機能を提供します。
|
|
これによって 1 つのプロセス
|
|
.\".Em tracing
|
|
(トレースするプロセス) が他のプロセス
|
|
.\".Em traced
|
|
(トレースされるプロセス) を制御できます。
|
|
トレースするプロセスは、最初にトレースされるプロセスにアタッチ
|
|
しなければなりません。
|
|
それから、そのプロセスの実行を制御するために
|
|
.Fn ptrace
|
|
システムコールを発行します。
|
|
プロセスのメモリおよびレジスタ状態へのアクセスも同様です。
|
|
トレースするセッションの期間中、トレースされるプロセスは
|
|
その親プロセス ID が (その結果の動作として) トレースするプロセスに
|
|
.Dq 親を変更
|
|
されます。
|
|
トレースするプロセスが同時に 1 つ以上のプロセスをアタッチすることは、
|
|
許可されます。
|
|
トレースするプロセスがその作業を完了したときには、そのトレースされる
|
|
プロセスをデタッチしなければなりません。
|
|
トレースするプロセスが最初にアタッチされている全てのプロセスをデタッチ
|
|
せずに exit した場合には、それらのプロセスは kill されます。
|
|
.Pp
|
|
ほとんどの場合、トレースされるプロセスは正常に実行されます。
|
|
ただし、トレースされるプロセスはシグナル
|
|
.Xr ( sigaction 2
|
|
を参照) を受信すると停止します。
|
|
トレースするプロセスは、
|
|
.Xr wait 2
|
|
または
|
|
.Dv SIGCHLD
|
|
シグナルによってこれを検知し、停止されたプロセスの状態を調査して、
|
|
それを終了させるか、または適切な形で実行を継続させます。
|
|
そのシグナルは、トレースされるプロセスの動作の結果として生成されたか、
|
|
.Xr kill 2
|
|
システムコールの使用による、通常のプロセスのシグナルかもしれません。
|
|
もしくは、アタッチ、システムコール、
|
|
またはトレースするプロセスによるステップの結果、
|
|
トレースする仕組みによって生成されたものかもしれません。
|
|
トレースしているプロセスは、そのシグナルを使用してプロセスの動作を観測する
|
|
ために
|
|
.Dv ( SIGTRAP
|
|
の様に) そのシグナルを横取りするか、もし適切であればそのシグナルを
|
|
そのプロセスに転送するかを、選択できます。
|
|
.Fn ptrace
|
|
システムコールは、これらすべてを制御するメカニズムです。
|
|
.Pp
|
|
.Fa request
|
|
引数は、どの操作を実行するかを指定します。
|
|
残りの引数の意味は操作によって異なります。
|
|
後述する 1 つの特殊なケースを除いて、
|
|
.Fn ptrace
|
|
呼び出しはすべてトレースするプロセスによって行われ、
|
|
.Fa pid
|
|
引数はトレースされるプロセスのプロセス ID を指定します。
|
|
.Fa request
|
|
引数は次のものにできます。
|
|
.Bl -tag -width 12n
|
|
.It Dv PT_TRACE_ME
|
|
この要求は、トレースされるプロセスが使用する唯一の要求です。
|
|
この要求は、プロセスがその親によってトレースされることを宣言します。
|
|
他の引数はすべて無視されます
|
|
(親プロセスが子プロセスをトレースしない場合は、
|
|
かなり混乱した結果になります。
|
|
トレースされるプロセスが停止すると、このプロセスは、
|
|
.Fn ptrace
|
|
によってしか実行を継続できません)。
|
|
プロセスがこの要求を使用し、
|
|
.Xr execve 2
|
|
またはそれに組み込まれているルーチン
|
|
(たとえば、
|
|
.Xr execv 3 )
|
|
を呼び出した場合、
|
|
そのプロセスは新しいイメージの最初の命令を実行する前に停止します。
|
|
また、実行される実行可能モジュールの
|
|
setuid または setgid ビットは無視されます。
|
|
.It Dv PT_READ_I , Dv PT_READ_D
|
|
これらの要求は、トレースされるプロセスのアドレス空間から 1 つの
|
|
.Vt int
|
|
データを読み取ります。
|
|
従来、
|
|
.Fn ptrace
|
|
は命令とデータについて区別されたアドレス空間のある
|
|
マシンを許容していました。
|
|
これが 2 つの要求がある理由です。
|
|
概念的には、
|
|
.Dv PT_READ_I
|
|
が命令空間から読み取り、
|
|
.Dv PT_READ_D
|
|
がデータ空間から読み取ります。
|
|
現在の
|
|
.Fx
|
|
システムでは、これらの 2 つの要求は完全に同一です。
|
|
.Fa addr
|
|
引数が、読取りが行われる (トレースされるプロセスの仮想アドレス空間内の)
|
|
アドレスを指定します。
|
|
このアドレスはどのような境界調整制約も満たす必要はありません。
|
|
読み取られた値は
|
|
.Fn ptrace
|
|
からの戻り値として返されます。
|
|
.It Dv PT_WRITE_I , Dv PT_WRITE_D
|
|
これらの要求は
|
|
.Dv PT_READ_I
|
|
および
|
|
.Dv PT_READ_D
|
|
と同様ですが、読み取るのではなく書き込むところが異なります。
|
|
.Fa data
|
|
引数で書き込まれる値を指定します。
|
|
.It Dv PT_IO
|
|
この要求によって、トレースされるプロセスのアドレス空間内にある
|
|
任意量のデータの読取りと書込みが有効となります。
|
|
.Fa addr
|
|
引数は、以下のように定義される
|
|
.Vt "struct ptrace_io_desc"
|
|
へのポインタを指定します。
|
|
.Bd -literal
|
|
struct ptrace_io_desc {
|
|
int piod_op; /* I/O 操作 */
|
|
void *piod_offs; /* 子オフセット */
|
|
void *piod_addr; /* 親オフセット */
|
|
size_t piod_len; /* 要求の長さ */
|
|
};
|
|
|
|
/*
|
|
* piod_op で指定される操作
|
|
*/
|
|
#define PIOD_READ_D 1 /* データ空間からの読取り */
|
|
#define PIOD_WRITE_D 2 /* データ空間への書込み */
|
|
#define PIOD_READ_I 3 /* 命令空間からの読取り */
|
|
#define PIOD_WRITE_I 4 /* 命令空間への書込み */
|
|
.Ed
|
|
.Pp
|
|
.Fa data
|
|
引数は無視されます。
|
|
実際に読み書きされたバイト数は、上記の
|
|
.Va piod_len
|
|
に入れられ返されます。
|
|
.It Dv PT_CONTINUE
|
|
トレースされるプロセスは実行を継続します。
|
|
.Fa addr
|
|
引数は、実行が再開される場所 (プログラムカウンタの新しい値)、
|
|
または実行が停止されたところで再開されることを示す
|
|
.Po Vt caddr_t Pc Ns 1
|
|
を指定します。
|
|
.Fa data
|
|
引数には、トレースされるプロセスが実行を再開するときに受信するシグナル番号、
|
|
またはシグナルを送信しない場合には 0 を指定します。
|
|
.It Dv PT_STEP
|
|
トレースされるプロセスは 1 命令ずつステップ実行されます。
|
|
.Fa addr
|
|
引数には
|
|
.Po Vt caddr_t Pc Ns 1
|
|
を渡す必要があります。
|
|
.Fa data
|
|
には実行の再開のために、トレースされたプロセスへ配信されるべきシグナルの数を
|
|
与えます。
|
|
または、送られるべきシグナルが無い場合には 0 を与えます。
|
|
.It Dv PT_KILL
|
|
トレースされるプロセスは、あたかも
|
|
.Dv SIGKILL
|
|
を配信シグナルとして
|
|
.Dv PT_CONTINUE
|
|
が使用されたかのように、終了します。
|
|
.It Dv PT_ATTACH
|
|
この要求は、他の無関係なプロセスの制御を取得し、
|
|
そのトレースを開始します。
|
|
トレースされるプロセスからの協力は必要としません。
|
|
このケースでは、
|
|
.Fa pid
|
|
にトレースされるプロセスのプロセス ID を指定し、
|
|
他の 2 つの引数は無視されます。
|
|
この要求では、ターゲットプロセスがトレースする
|
|
プロセスと同じ実 UID を持つこと、
|
|
それが setuid または setgid された実行可能モジュールでないことが
|
|
要求されます (トレースするプロセスが root として実行されている場合、
|
|
これらの制約は適用されません)。
|
|
トレースするプロセスは、新たにトレースされるプロセスを停止させ、
|
|
あたかも最初からずっとトレースしていたかのように制御できます。
|
|
.It Dv PT_DETACH
|
|
この要求は PT_CONTINUE と類似していますが、実行を継続する別の場所を
|
|
指定できないこと、および要求が成功した後、
|
|
トレースされていたプロセスはもはやトレースされず、
|
|
通常どおり実行を継続することが異なります。
|
|
.It Dv PT_GETREGS
|
|
この要求は、トレースされるプロセスのマシンレジスタを、
|
|
.Fa addr
|
|
が指す
|
|
.Do
|
|
.Vt "struct reg"
|
|
.Dc
|
|
.In ( machine/reg.h
|
|
内に定義されています) 内に読み取ります。
|
|
.It Dv PT_SETREGS
|
|
この要求は
|
|
.Dv PT_GETREGS
|
|
の逆です。
|
|
.Fa addr
|
|
が指す
|
|
.Do
|
|
.Vt "struct reg"
|
|
.Dc
|
|
.In ( machine/reg.h
|
|
内に定義されています)
|
|
からトレースされるプロセスのマシンレジスタをロードします。
|
|
.It Dv PT_GETFPREGS
|
|
この要求はトレースされるプロセスの浮動小数点レジスタを
|
|
.Fa addr
|
|
が指す
|
|
.Do
|
|
.Vt "struct fpreg"
|
|
.Dc
|
|
.In ( machine/reg.h
|
|
に定義されています) に読み取ります。
|
|
.It Dv PT_SETFPREGS
|
|
この要求は
|
|
.Dv PT_GETFPREGS
|
|
の反対です。
|
|
.Fa addr
|
|
が指す
|
|
.Do
|
|
.Vt "struct fpreg"
|
|
.Dc
|
|
.In ( machine/reg.h
|
|
内に定義されています)
|
|
からトレースされるプロセスの浮動小数点レジスタをロードします。
|
|
.It Dv PT_GETDBREGS
|
|
この要求はトレースされるプロセスのデバッグレジスタを
|
|
.Fa addr
|
|
が指す
|
|
.Do
|
|
.Vt "struct dbreg"
|
|
.Dc
|
|
.In ( machine/reg.h
|
|
内に定義されています) に読み取ります。
|
|
.It Dv PT_SETDBREGS
|
|
この要求は
|
|
.Dv PT_GETDBREGS
|
|
の反対です。
|
|
.Fa addr
|
|
の指す
|
|
.Do
|
|
.Vt "struct dbreg"
|
|
.Dc
|
|
.In ( machine/reg.h
|
|
内に定義されています)
|
|
からトレースされるプロセスのデバッグレジスタにロードします。
|
|
.It Dv PT_LWPINFO
|
|
この要求は、トレースされるプロセスが停止する原因となった
|
|
(軽量プロセスとしても知られる) カーネルスレッドについての情報を
|
|
獲得するために使用されます。
|
|
.Fa addr
|
|
引数は以下のように定義される
|
|
.Vt "struct ptrace_lwpinfo"
|
|
へのポインタを指定します:
|
|
.Bd -literal
|
|
struct ptrace_lwpinfo {
|
|
lwpid_t pl_lwpid; /* LWP 識別子 */
|
|
int pl_event; /* 受け取ったイベント */
|
|
};
|
|
.Ed
|
|
.Pp
|
|
.Fa data
|
|
引数は、呼び出し側に知られている構造体の大きさに設定されます。
|
|
これにより、古いプログラムに影響を与えること無しに、
|
|
この構造体を大きくすることができます。
|
|
.El
|
|
.Pp
|
|
さらにマシン固有の要求が存在することがあります。
|
|
.Sh 戻り値
|
|
いくつかの要求で
|
|
.Fn ptrace
|
|
はエラー以外の場合にも \-1 を返します。
|
|
曖昧さをなくすためには、呼び出しの前に
|
|
.Va errno
|
|
を 0 に設定し、後でチェックします。
|
|
.Sh エラー
|
|
.Fn ptrace
|
|
システムコールは次の場合に処理に失敗します。
|
|
.Bl -tag -width Er
|
|
.It Bq Er ESRCH
|
|
.Bl -bullet -compact
|
|
.It
|
|
指定されたプロセス ID を持つプロセスが存在しません。
|
|
.El
|
|
.It Bq Er EINVAL
|
|
.Bl -bullet -compact
|
|
.It
|
|
プロセスが自分自身に対して
|
|
.Dv PT_ATTACH
|
|
を使おうとしました。
|
|
.It
|
|
.Fa request
|
|
引数が正しい要求の 1 つではありませんでした。
|
|
.It
|
|
.Dv PT_CONTINUE
|
|
へのシグナル番号
|
|
.Fa ( data )
|
|
が 0 でないか、または正しいシグナル番号ではありませんでした。
|
|
.It
|
|
.Dv PT_GETREGS ,
|
|
.Dv PT_SETREGS ,
|
|
.Dv PT_GETFPREGS ,
|
|
.Dv PT_SETFPREGS ,
|
|
.Dv PT_GETDBREGS
|
|
または
|
|
.Dv PT_SETDBREGS
|
|
が、有効なレジスタセットを設定せずに使用されました
|
|
(これが真になるのは、通常、システムプロセスについてのみです)。
|
|
.El
|
|
.It Bq Er EBUSY
|
|
.Bl -bullet -compact
|
|
.It
|
|
.Dv PT_ATTACH
|
|
が既にトレース中のプロセスについて使用されました。
|
|
.It
|
|
要求をしているプロセス以外のプロセスによって、トレースされるプロセスを
|
|
操作しようとする要求が試みられました。
|
|
.It
|
|
要求
|
|
.Dv ( PT_ATTACH
|
|
以外の) が停止されていないプロセスを指定しました。
|
|
.El
|
|
.It Bq Er EPERM
|
|
.Bl -bullet -compact
|
|
.It
|
|
要求
|
|
.Dv ( PT_ATTACH
|
|
以外の) が、まったくトレースされていないプロセスを操作しようとしました。
|
|
.It
|
|
前述の
|
|
.Dv PT_ATTACH
|
|
で説明した条件を満たさないプロセスについて
|
|
.Dv PT_ATTACH
|
|
を使おうとしました。
|
|
.El
|
|
.El
|
|
.Sh 関連項目
|
|
.Xr execve 2 ,
|
|
.Xr sigaction 2 ,
|
|
.Xr wait 2 ,
|
|
.Xr execv 3 ,
|
|
.Xr i386_clr_watch 3 ,
|
|
.Xr i386_set_watch 3
|
|
.Sh 歴史
|
|
.Fn ptrace
|
|
関数は
|
|
.At v7
|
|
で登場しました。
|