|
|
@@ -12,7 +12,9 @@ import (
|
|
|
klog "github.com/sirupsen/logrus"
|
|
|
"os"
|
|
|
"path/filepath"
|
|
|
+ "strconv"
|
|
|
"strings"
|
|
|
+ "syscall"
|
|
|
)
|
|
|
|
|
|
// AttachStackUprobes
|
|
|
@@ -139,7 +141,6 @@ func (t *Tracer) AttachJVMStackUprobes(pid uint32, appInfo AppInfo) ([]link.Link
|
|
|
}
|
|
|
|
|
|
func FindNativeSoFromMapped(pid uint32, prefix, suffix string) (string, error) {
|
|
|
- // todo rootfs
|
|
|
mapsFile := fmt.Sprintf("/proc/%d/maps", pid)
|
|
|
tmpFile, err := os.Open(mapsFile)
|
|
|
if err != nil {
|
|
|
@@ -147,15 +148,33 @@ func FindNativeSoFromMapped(pid uint32, prefix, suffix string) (string, error) {
|
|
|
}
|
|
|
defer tmpFile.Close()
|
|
|
|
|
|
- // 使用 bufio.Scanner 逐行读取文件内容
|
|
|
+ var selectedPath string
|
|
|
+ var maxTimestamp int64
|
|
|
+ fallbackPaths := make(map[string]struct{}) // 使用 map 去重
|
|
|
+
|
|
|
scanner := bufio.NewScanner(tmpFile)
|
|
|
for scanner.Scan() {
|
|
|
line := scanner.Text()
|
|
|
- // 检查路径部分是否包含 "NativeAgentSo" 且以 ".tmp" 结尾
|
|
|
if strings.Contains(line, prefix) && strings.HasSuffix(line, suffix) {
|
|
|
parts := strings.Fields(line)
|
|
|
if len(parts) > 5 {
|
|
|
- return parts[len(parts)-1], nil // 返回路径
|
|
|
+ path := parts[len(parts)-1]
|
|
|
+ baseName := filepath.Base(path)
|
|
|
+
|
|
|
+ if strings.HasPrefix(baseName, prefix) && strings.HasSuffix(baseName, suffix) {
|
|
|
+ middle := strings.TrimSuffix(strings.TrimPrefix(baseName, prefix), suffix)
|
|
|
+ segments := strings.Split(middle, ".")
|
|
|
+ if len(segments) >= 2 {
|
|
|
+ timestampStr := segments[len(segments)-1]
|
|
|
+ timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
|
|
|
+ if err == nil && timestamp > maxTimestamp {
|
|
|
+ maxTimestamp = timestamp
|
|
|
+ selectedPath = path
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ fallbackPaths[path] = struct{}{}
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -164,5 +183,31 @@ func FindNativeSoFromMapped(pid uint32, prefix, suffix string) (string, error) {
|
|
|
return "", fmt.Errorf("error reading maps file: %v", err)
|
|
|
}
|
|
|
|
|
|
+ if selectedPath != "" {
|
|
|
+ return selectedPath, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ var latestPath string
|
|
|
+ var latestModTime int64
|
|
|
+ for path := range fallbackPaths {
|
|
|
+ info, err := os.Stat(path)
|
|
|
+ if err != nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ stat, ok := info.Sys().(*syscall.Stat_t)
|
|
|
+ if !ok {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ modTime := stat.Mtim.Sec
|
|
|
+ if modTime > latestModTime {
|
|
|
+ latestModTime = modTime
|
|
|
+ latestPath = path
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if latestPath != "" {
|
|
|
+ return latestPath, nil
|
|
|
+ }
|
|
|
+
|
|
|
return "", fmt.Errorf("no matching path found")
|
|
|
}
|