PTRACE(2) — NEWS-OS Programmer’s Manual
名称
ptrace − プロセスのトレース
形式
#include <sys/signal.h>
#include <sys/ptrace.h>
ptrace(request, pid, addr, data)
int request, pid, ∗addr, data;
解説
ptrace は、 親プロセスが、 子プロセスの実行を 制御し、 そのコアイメージを 調べて変更するための手段を 提供します。 このコールの主な使い道は、 ブレークポイントによるデバッギングの実行です。 4 つの引数があり、 それらの解釈は request 引数に依存します。 普通、 pid は、 トレースされるプロセスのプロセスIDであり、 このトレースされるプロセスは、 トレースを 実行するプロセスの子プロセス(それ以上遠い子孫は不可)でなければなりません。 トレースされているプロセスは、 “イリーガルな命令”のような内部的に生成されたシグナルか、 または“割り込み”のような外部的に生成されたシグナルの、 いずれかのシグナルに遭遇するまでは、 正常に稼働します。 シグナルの一覧は、 sigvec(2) を 参照してください。 シグナルに遭遇すると、 トレースされているプロセスは、 停止状態に入り、 それが wait(2) によって、 その親へ通知されます。 子が停止状態にあるときには、 ptrace を 使用して、 そのコアイメージを 調べて修正することができます。 必要があれば、 その後、 別の ptrace request を 用いて、 その子を 終了または再開させることができます。 その場合、 シグナルを 無視させることもできます。
request 引数の値が、 次のようにコールの動作を 決定します。
PT_TRACE_ME
この request は、 子プロセスによって使用される唯一のリクエストです。 これは、 プロセスがその親によってトレースされることを 宣言します。 他のすべての引数は無視されます。 親がその子を トレースするつもりのない場合には、 予期しない結果になります。
PT_READ_I,PT_READ_D
子プロセスのアドレススペースの addr にあるワードが返されます。 I スペースと D スペースが分離されている(例えば、 pdp-11 では当初から分離されている)場合には、 PT_READ_I は、 I スペースを 示し、 PT_READ_D は、 D スペースを 示します。 addr は、 マシンによっては偶数でなければなりません。 子は停止していなければなりません。 入力 data は無視されます。
PT_READ_U
addr に対応するシステムのプロセスデータ領域のワードが返されます。 addr は、 マシンによっては偶数でなければならず、 512 より小さな値でなければなりません。 このスペースには、 レジスタと、 そのプロセスに関する他の情報が収められています。 そのレイアウトは、 システム内にある user 構造体に対応しています。
PT_WRITE_I,PT_WRITE_D
与えられた data が、 addr に対応する、 そのプロセスのアドレススペース内のワードの位置に書き込まれます。 addr は、マシンによっては偶数でなければなりません。 役に立つ値は返されません。 I スペースと D スペースが分離されている場合には、PT_WRITE_I は、 I スペースを 示し、PT_WRITE_D は、D スペースを 示します。 別のプロセスが純プロシージャファイルを 実行している場合には、 そのファイルへの書き込みは失敗します。
PT_WRITE_U
そのプロセスのシステムデータが書き込まれます。 スペースなどは、PT_READ_U での読み取りの場合と同様です。 このリクエストでは、 いくつかのロケーションにしか書き込みができません。 汎用レジスタ、 浮動小数点ステータスおよびレジスタ、 プロセッサステータスワードのいくつかのビットだけです。
PT_CONTINUE
data 引数は、 シグナル番号として解釈され、 あたかも子がそのシグナルを 受け取ったかのように、 子プロセスの実行がロケーション addr で再開されます。 通常、 このシグナル番号は、 停止を 引き起こしたシグナルが無視されるべきであることを 示す 0、 またはどのシグナルが停止を 引き起こしたのかを 示す、 そのプロセスのイメージから取り出された値のいずれかです。 addr が (int ∗)1 である場合には、 実行は停止したところから再開されます。
PT_KILL
トレースされているプロセスは終了します。
PT_STEP
PT_CONTINUE の場合と同様に、 実行が再開されます。 しかし、 最低 1つの命令の実行が終ると、 即座に実行は再停止します。 この停止を 引き起こすシグナルは SIGTRAP です (NEWSでは、T-ビットが使用され、 1つの命令だけが実行されます)。 これは、 ブレークポイントを 実現するためのメカニズムの一部です。
前述のとおり、 これらのコール(PT_TRACE_ME以外)は、 対象となるプロセスが停止しているときにだけ使用することができます。 wait コールは、 いつプロセスが停止するのかを 決定するために使用することができます。 そのような場合には、 wait によって返される“終了”ステータスは、 本当の終了ではなく、 停止を 示す値 0177 になります。
不正な手段を 防止するために、 ptrace は、 それ以降の execve(2) コールにおけるセットユーザIDおよびセットグループID機能を 禁止しています。 トレースされるプロセスが execve を 呼び出した場合には、 新しいイメージの最初の命令が実行される前に、 シグナル SIGTRAP を 出し、 そのプロセスは停止します。
NEWSでは、 “ワード”は 32 ビットの整数を 意味します。また、アドレスに関する “偶数”の制限は適用されません。
リターン値
コールが成功した場合には、 値 0 が返されます。 コールが失敗した場合には、 −1 が返され、 グローバル変数 errno がエラーを 示すようにセットされます。
エラー
[EIO] 要求コードが無効である。
[ESRCH] 指定されたプロセスが存在していない。
[EIO] 与えられたシグナル番号が無効である。
[EIO] 指定されたアドレスが範囲外である。
[EPERM] 指定されたプロセスを トレースすることができない。
関連事項
バグ
ptrace は、 ユニークですが、 わかりにくいものです。 これは、 オープンして読み取りと書き込みができる スペシャルファイルで置き替える必要があります。 そのようなファイルで置き替えた場合、 制御機能は、 そのファイルに対する ioctl(2) コールで実現することができます。 このようにすれば、 理解が容易になり、 性能も改善されます。
PT_TRACE_ME のコールは、 普通に扱えて、 停止を 引き起こさないシグナルを 指定できるようにする必要があります。 このようにすれば、 例えば、 (“イリーガルな命令”のシグナルを 頻繁に使用するような)シミュレートされた浮動小数点数のあるプログラムを 効率的にデバッグすることができます。
エラーを 示す −1 は、 合法的な関数値です。エラーではありません。 errno (intro(2) 参照)を 使用すれば、 エラーであるかどうかを 判定することができます。
システムコールがあったときにプロセスを 停止することができるようにする必要があります。 このようにすれば、 完璧に制御された環境を 提供することができます。
NEWS-OSRelease 4.1C