Hello! I've ran into a weird issue so far that I have not been able to pin down thus far. Keep in mind this MAY NOT be a golang issue/bug, rather a linux kernel oddity that I haven't picked up on yet.
I'm experimenting with VM_PROCESS_READV to read the heap of a remote process on linux.
the relevant (not complete) code snippet is below, testing with using a local process at the moment. I have no idea what is going wrong. I allocate a local 400 byte buffer, check it again right before the syscall, use the syscall, (which returns it read 400 bytes), check it after the syscall, and the buffer is magically only 100 bytes. Any clue as to why this might be happening?
package main
import (
"bytes"
"fmt"
"os"
"runtime/debug"
"strconv"
"syscall"
"unsafe"
)
const process_vm_readv = 310
type IOVec struct {
iov_base unsafe.Pointer
iov_len uintptr
}
func main() {
var pid uint64 = uint64(os.Getpid())
local := new(IOVec)
debug.SetGCPercent(-1)
buf := make([]byte, 400, 400)
findme := bytes.Repeat([]byte("ABCD"), 25)
metoo := bytes.Repeat([]byte("YEAH"), 1)
fmt.Printf("find: %p \n", &findme)
fmt.Printf("metoo: %p \n", &metoo)
local.iov_base = unsafe.Pointer(&buf)
local.iov_len = 400
remote := new(IOVec)
remote.iov_base = unsafe.Pointer(&findme)
remote.iov_len = 400
fmt.Printf("After syscall: len(buf) = %d, cap(buf) = %d\n", len(buf), cap(buf))
a, b, c := syscall.Syscall6(process_vm_readv, uintptr(pid), uintptr(unsafe.Pointer(local)), 1, uintptr(unsafe.Pointer(remote)), 1, 0)
fmt.Printf("After syscall: len(buf) = %d, cap(buf) = %d\n", len(buf), cap(buf))
fmt.Printf("%v, %v, %v\n", a, b, c)
fmt.Printf("%#v, %#v, %#v\n", local, remote, buf)
}