package tracer import ( "fmt" "github.com/coroot/coroot-node-agent/ebpftracer/tracer/ptrace" "github.com/coroot/coroot-node-agent/utils" klog "github.com/sirupsen/logrus" "math" "os" "runtime" ) type AllocationDetails struct { StartAddr uint64 EndAddr uint64 //NumCPU uint64 } func Allocate(pid int) (*AllocationDetails, error) { nCPU, err := utils.GetCPUCount() if err != nil { return nil, err } mapSize := uint64(os.Getpagesize() * nCPU * 8) addr, err := remoteAllocate(pid, mapSize) if err != nil { return nil, err } return &AllocationDetails{ StartAddr: addr, EndAddr: addr + mapSize, //NumCPU: uint64(nCPU), }, nil } func remoteAllocate(pid int, mapSize uint64) (uint64, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() program, err := ptrace.NewTracedProgram(pid) if err != nil { return 0, err } defer func() { klog.Info("Detaching from process ", pid) err := program.Detach() if err != nil { klog.Error(err, "Failed to detach ptrace", "pid", pid) } }() if err := program.SetMemLockInfinity(); err != nil { klog.Error(err, "Failed to set memlock on process") } else { klog.Info("Set memlock on process successfully") } fd := -1 addr, err := program.Mmap(mapSize, uint64(fd)) if err != nil { return 0, err } if addr == math.MaxUint64 { // On success, mmap() returns a pointer to the mapped area. // On error, the value MAP_FAILED (that is, (void *) -1) is returned return 0, fmt.Errorf("mmap MAP_FAILED") } err = program.Madvise(addr, mapSize) if err != nil { return 0, err } err = program.Mlock(addr, mapSize) if err != nil { return 0, err } return addr, nil }