Linux

使用 process_vm_readv 讀取任意數量的記憶體

  • February 9, 2019

對於 process_vm_readv,linux 手冊頁指出:

$$ … $$(避免)在單個遠端 iovec 元素中跨越記憶體頁面(通常為 4KiB)。(相反,將遠端讀取拆分為兩個 remote_iov 元素,並將它們合併回單個寫入 local_iov 條目。第一個讀取條目上升到頁面邊界,而第二個讀取條目從下一頁邊界開始。)

我明白為什麼這是一件事,但我不太明白我應該如何解決它。我是否需要以某種方式找出頁面邊界在哪裡?或者只要我提供 2 個 remote_iov 元素,該函式是否可以自行解決?如果我閱讀超過 4kiB 並且可能跨越 2 個頁面邊界,我是否需要將遠端元素拆分為 3 個部分?

您應該真正閱讀整個段落——拆分 iovecs 的方式並不是硬性要求。它只應該在部分閱讀的情況下有所幫助,儘管目前尚不清楚它如何提供幫助;-)

該聯機幫助頁非常可疑且令人困惑。我的測試表明,如果列表中的第一個 iovec 的地址不是有效地址,process_vm_readv()則總是會出錯,但如果沒有映射到所跨越的任何頁面或其餘 iovec(這是預期和有用,但與下面強調的部分相矛盾)。iov_start``remote_iov``iov_start + iov_len

但是請注意,這些系統呼叫在執行 read/write 之前不會檢查遠端程序中的記憶體區域。因此,如果其中一個 元素指向遠端程序中的無效記憶體區域,則可能會導致部分讀/寫(請參閱返回值) 。remote_iov超出該點將不會嘗試進一步的讀/寫。在嘗試從遠端程序讀取未知長度的數據(例如以 null 結尾的 C 字元串)時,請記住這一點,避免在單個遠端 iovec 元素中跨越記憶體頁面(通常為 4KiB)。(相反,將遠端讀取分成兩部分 remote_iov 元素並將它們合併回單個寫入 local_iov條目。第一個讀取條目上升到頁面邊界,而第二個讀取條目從下一頁邊界開始。)

$$ … $$ 如果發生部分讀/寫,此返回值可能小於請求的字節總數。(部分傳輸適用於 iovec 元素的粒度。這些系統呼叫不會執行拆分單個 iovec 元素的部分傳輸。)

引用自:https://unix.stackexchange.com/questions/499537