allocate.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package tracer
  2. import (
  3. "fmt"
  4. "github.com/coroot/coroot-node-agent/ebpftracer/tracer/ptrace"
  5. "github.com/coroot/coroot-node-agent/utils"
  6. klog "github.com/sirupsen/logrus"
  7. "math"
  8. "os"
  9. "runtime"
  10. )
  11. type AllocationDetails struct {
  12. StartAddr uint64
  13. EndAddr uint64
  14. //NumCPU uint64
  15. }
  16. func Allocate(pid int) (*AllocationDetails, error) {
  17. nCPU, err := utils.GetCPUCount()
  18. if err != nil {
  19. return nil, err
  20. }
  21. mapSize := uint64(os.Getpagesize() * nCPU * 8)
  22. addr, err := remoteAllocate(pid, mapSize)
  23. if err != nil {
  24. return nil, err
  25. }
  26. return &AllocationDetails{
  27. StartAddr: addr,
  28. EndAddr: addr + mapSize,
  29. //NumCPU: uint64(nCPU),
  30. }, nil
  31. }
  32. func remoteAllocate(pid int, mapSize uint64) (uint64, error) {
  33. runtime.LockOSThread()
  34. defer runtime.UnlockOSThread()
  35. program, err := ptrace.NewTracedProgram(pid)
  36. if err != nil {
  37. return 0, err
  38. }
  39. defer func() {
  40. klog.Info("Detaching from process ", pid)
  41. err := program.Detach()
  42. if err != nil {
  43. klog.Error(err, "Failed to detach ptrace", "pid", pid)
  44. }
  45. }()
  46. if err := program.SetMemLockInfinity(); err != nil {
  47. klog.Error(err, "Failed to set memlock on process")
  48. } else {
  49. klog.Info("Set memlock on process successfully")
  50. }
  51. fd := -1
  52. addr, err := program.Mmap(mapSize, uint64(fd))
  53. if err != nil {
  54. return 0, err
  55. }
  56. if addr == math.MaxUint64 {
  57. // On success, mmap() returns a pointer to the mapped area.
  58. // On error, the value MAP_FAILED (that is, (void *) -1) is returned
  59. return 0, fmt.Errorf("mmap MAP_FAILED")
  60. }
  61. err = program.Madvise(addr, mapSize)
  62. if err != nil {
  63. return 0, err
  64. }
  65. err = program.Mlock(addr, mapSize)
  66. if err != nil {
  67. return 0, err
  68. }
  69. return addr, nil
  70. }