必要な量のメモリを読み取るには、 process_vm_readv を使用します。

必要な量のメモリを読み取るには、 process_vm_readv を使用します。

process_vm_readv の場合、Linux のマニュアルページには次のように指定されています。

[...](防止)単一のリモートiovec要素のスパニングメモリページ(通常4KiB)。 (代わりに、リモート読み取りを2つのremote_iov要素に分割し、それを単一の書き込みlocal_iov項目にマージします。最初の読み取り項目はページ境界まで上がり、2番目の読み取り項目は次のページ境界から始まります。)

これがなぜ問題なのかは理解していますが、問題を解決する方法はよくわかりません。ページ境界がどこにあるかを調べる必要がありますか?それとも、2つのremote_iov要素を提供する限り、関数はこの問題を自分で解決しますか? 4kiB以上を読み、2ページの境界にまたがる可能性がある場合は、リモート要素を3つの部分に分割する必要がありますか?

ベストアンサー1

実際には、段落全体を読む必要があります。 iovecを分割するこれらの方法は必須ではありません。これだけしなければならない部分的に読むことは役に立ちますが、どのように役立つかわかりません。 ;-)

マンページはやや複雑で混乱しています。私のテストでは、process_vm_readv()リストの最初のiovecが有効なアドレスではありませんが、iovecが任意のページにまたがっている場合、または残りのiovecがマッピング解除されている場合(予想され、便利ですが)、常にエラーが発生します。以下に強調表示されたセクションと矛盾します)。iov_startremote_ioviov_start + iov_len

ただし、これらのシステムコールはリモートプロセスのメモリ領域をチェックしないことに注意してください。読み取り/書き込み操作が実行されるまで。だから部分読み取り/書き込み(戻り値を参照) remote_iov これは、要素の1つがリモートプロセスの誤ったメモリ領域を指している場合に発生する可能性があります。この時点以降、これ以上読み書きは試行されません。リモートプロセスで長さが不明なデータ(たとえば、nullで終わるC文字列)を読み取ろうとするときは、この点に注意して、単一のリモートiovec要素からメモリページ(通常4KiB)を拡張しないでください。 (代わりに、リモート読み取りを2つの remote_iov 要素に分割し、再び単一の書き込み local_iov項目にマージします。最初の読み取り項目はページ境界まで上がり、2番目の読み取り項目は次のページ境界から始まります。)

[...]

部分読み取り/書き込みが発生した場合、この戻り値は要求された合計バイト数より少なくなる可能性があります。 (部分移転iovec要素に適用される粒度。これらのシステムコールは、個々のiovec要素を分割する部分的な転送を実行しません。.)

おすすめ記事