util.go 3.0 KB

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