util.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package containers
  2. import (
  3. "debug/elf"
  4. "fmt"
  5. . "github.com/coroot/coroot-node-agent/utils/modelse"
  6. klog "github.com/sirupsen/logrus"
  7. "os"
  8. "os/exec"
  9. "regexp"
  10. "runtime"
  11. "strings"
  12. )
  13. var libjvmRegex = regexp.MustCompile(`.*/libjvm\.so`)
  14. func GetExeType(pid uint32, rootfs string) CodeType {
  15. mapsFilePath := fmt.Sprintf("%sproc/%d/maps", "/", pid)
  16. data, err := os.ReadFile(mapsFilePath)
  17. if err != nil {
  18. klog.WithError(err).Errorf("Failed to read %s: %s", mapsFilePath)
  19. return CodeTypeUnknown
  20. }
  21. content := string(data)
  22. if libjvmRegex.MatchString(content) {
  23. //fmt.Println("is java process")
  24. if isJavaAotProcess(pid, rootfs) {
  25. //fmt.Println("is javaAot process")
  26. return CodeTypeJavaAot
  27. }
  28. return CodeTypeJava
  29. } else if isJavaAotProcess(pid, rootfs) {
  30. //fmt.Println("is javaAot process")
  31. return CodeTypeJavaAot
  32. } else if isGoProcess(pid, rootfs) {
  33. //fmt.Println("is go process")
  34. return CodeTypeGo
  35. } else if isNetCoreProcess(pid, rootfs) {
  36. // fmt.Println("is netcore process")
  37. return CodeTypeNetCoreAot
  38. }
  39. return CodeTypeUnknown
  40. }
  41. // isJavaAotProcess checks if the process with the given PID is a GraalVM native image
  42. func isJavaAotProcess(pid uint32, rootfs string) bool {
  43. // Get the executable path for the given PID
  44. exePath, err := os.Readlink(fmt.Sprintf("%sproc/%d/exe", "/", pid))
  45. if err != nil {
  46. fmt.Printf("Error reading executable path for PID %d: %v\n", pid, err)
  47. return false
  48. }
  49. // Read the content of the executable file
  50. content, err := os.ReadFile(fmt.Sprintf("%s%s", rootfs, exePath))
  51. if err != nil {
  52. klog.WithError(err).Errorf("Error reading executable file for PID %d\n", pid)
  53. return false
  54. }
  55. // Check if the file contains the "graal_attach_thread" string
  56. if strings.Contains(string(content), "graal_attach_thread") {
  57. return true
  58. }
  59. return false
  60. }
  61. func isNetCoreProcess(pid uint32, rootfs string) bool {
  62. path, err := getProcessPath(pid)
  63. if err != nil {
  64. //fmt.Printf("无法获取进程路径:%s\n", err)
  65. return false
  66. }
  67. ef, err := elf.Open(rootfs + path)
  68. if err != nil {
  69. klog.WithError(err).Error("failed to open as elf binary")
  70. return false
  71. }
  72. defer ef.Close()
  73. __managedcode := ef.Section("__managedcode")
  74. if __managedcode != nil {
  75. fmt.Println("is a netcore process")
  76. return true
  77. }
  78. return false
  79. }
  80. func isGoProcess(pid uint32, rootfs string) bool {
  81. path, err := getProcessPath(pid)
  82. if err != nil {
  83. klog.WithError(err).Error("failed to open as elf binary")
  84. return false
  85. }
  86. ef, err := elf.Open(rootfs + path)
  87. if err != nil {
  88. fmt.Println("failed to open as elf binary", err)
  89. return false
  90. }
  91. defer ef.Close()
  92. gopclntabSection := ef.Section(".gopclntab")
  93. if gopclntabSection != nil {
  94. //fmt.Println("is a go process")
  95. return true
  96. }
  97. return false
  98. }
  99. func getProcessPath(pid uint32) (string, error) {
  100. switch runtime.GOOS {
  101. case "linux":
  102. return getLinuxProcessPath(pid)
  103. default:
  104. return "", fmt.Errorf("不支持的操作系统:%s", runtime.GOOS)
  105. }
  106. }
  107. func getLinuxProcessPath(pid uint32) (string, error) {
  108. procPath := fmt.Sprintf("/proc/%d/exe", pid)
  109. path, err := os.Readlink(procPath)
  110. if err != nil {
  111. return "", err
  112. }
  113. return path, nil
  114. }
  115. func executeCommand(name string, args ...string) (string, error) {
  116. cmd := exec.Command(name, args...)
  117. out, err := cmd.Output()
  118. if err != nil {
  119. return "", err
  120. }
  121. return string(out), nil
  122. }