package containers import ( "debug/elf" "fmt" "io/ioutil" "log" "os" "os/exec" "regexp" "runtime" "strings" ) var libjvmRegex = regexp.MustCompile(`.*/libjvm\.so`) func GetExeType(pid uint32) CodeType { mapsFilePath := fmt.Sprintf("/proc/%d/maps", pid) data, err := ioutil.ReadFile(mapsFilePath) if err != nil { log.Fatalf("Failed to read %s: %s", mapsFilePath, err) } content := string(data) if libjvmRegex.MatchString(content) { fmt.Println("is java process") if isJavaAotProcess(pid) { fmt.Println("is javaAot process") return CodeTypeJavaAot } return CodeTypeJava } else if isJavaAotProcess(pid) { fmt.Println("is javaAot process") return CodeTypeJavaAot } else if isGoProcess(pid) { return CodeTypeGo fmt.Println("is go process") } else if isNetCoreProcess(pid) { fmt.Println("is netcore process") return CodeTypeNetCore } return CodeTypeUnknown } // isJavaAotProcess checks if the process with the given PID is a GraalVM native image func isJavaAotProcess(pid uint32) bool { // Get the executable path for the given PID exePath, err := os.Readlink(fmt.Sprintf("/proc/%d/exe", pid)) if err != nil { fmt.Printf("Error reading executable path for PID %d: %v\n", pid, err) return false } // Read the content of the executable file content, err := ioutil.ReadFile(exePath) if err != nil { fmt.Printf("Error reading executable file for PID %d: %v\n", pid, err) return false } // Check if the file contains the "graal_attach_thread" string if strings.Contains(string(content), "graal_attach_thread") { return true } return false } func isNetCoreProcess(pid uint32) bool { path, err := getProcessPath(pid) if err != nil { fmt.Printf("无法获取进程路径:%s\n", err) return false } ef, err := elf.Open(path) if err != nil { fmt.Println("failed to open as elf binary", err) return false } defer ef.Close() __managedcode := ef.Section("__managedcode") if __managedcode != nil { fmt.Println("is a netcore process") return true } return false } func isGoProcess(pid uint32) bool { path, err := getProcessPath(pid) if err != nil { fmt.Printf("无法获取进程路径:%s\n", err) return false } ef, err := elf.Open(path) if err != nil { fmt.Println("failed to open as elf binary", err) return false } defer ef.Close() gopclntabSection := ef.Section(".gopclntab") if gopclntabSection != nil { fmt.Println("is a go process") return true } return false } func getProcessPath(pid uint32) (string, error) { switch runtime.GOOS { case "linux": return getLinuxProcessPath(pid) default: return "", fmt.Errorf("不支持的操作系统:%s", runtime.GOOS) } } func getLinuxProcessPath(pid uint32) (string, error) { procPath := fmt.Sprintf("/proc/%d/exe", pid) path, err := os.Readlink(procPath) if err != nil { return "", err } return path, nil } func executeCommand(name string, args ...string) (string, error) { cmd := exec.Command(name, args...) out, err := cmd.Output() if err != nil { return "", err } return string(out), nil }