|
|
@@ -1,13 +1,22 @@
|
|
|
package ebpftracer
|
|
|
|
|
|
import (
|
|
|
+ "bufio"
|
|
|
+ "fmt"
|
|
|
"github.com/cilium/ebpf"
|
|
|
"github.com/cilium/ebpf/link"
|
|
|
"github.com/coroot/coroot-node-agent/ebpftracer/tracer"
|
|
|
+ "github.com/coroot/coroot-node-agent/ebpftracer/tracer/jattach"
|
|
|
"github.com/coroot/coroot-node-agent/utils"
|
|
|
+ . "github.com/coroot/coroot-node-agent/utils/modelse"
|
|
|
klog "github.com/sirupsen/logrus"
|
|
|
+ "os"
|
|
|
+ "path/filepath"
|
|
|
+ "strings"
|
|
|
)
|
|
|
|
|
|
+// AttachStackUprobes
|
|
|
+// default process stack
|
|
|
func (t *Tracer) AttachStackUprobes(path string, uprobes []tracer.Uprobe) []link.Link {
|
|
|
var links []link.Link
|
|
|
|
|
|
@@ -39,29 +48,61 @@ func (t *Tracer) AttachStackUprobes(path string, uprobes []tracer.Uprobe) []link
|
|
|
return links
|
|
|
}
|
|
|
|
|
|
-func (t *Tracer) AttachJVMStackUprobes(path string, uprobes []tracer.Uprobe) []link.Link {
|
|
|
- // TODO copy至目标进程读取
|
|
|
- //utils.GetDefaultAgentsPath("NativeAgent","libnativeAgent.so")
|
|
|
+// JVM process stack
|
|
|
+func (t *Tracer) AttachJVMStackUprobes(pid uint32, appInfo AppInfo) ([]link.Link, error) {
|
|
|
+ klog.Infoln("[Jvm stack uprobe] Attach Start AttachJVMStackUprobes", pid)
|
|
|
+ // TODO tiny Agent 注入
|
|
|
+ //argkv := "/opt/github/euspace/dist/package_dir/agents/NativeAgent/lib/apmAgent.jar=/opt/github/euspace/dist/package_dir/agents/NativeAgent"
|
|
|
+
|
|
|
+ nativeBasePath := utils.GetDefaultAgentsPath("NativeAgent")
|
|
|
+ kvPairs := []string{
|
|
|
+ fmt.Sprintf("%s=%s", filepath.Join(nativeBasePath, "lib", "apmAgent.jar"), nativeBasePath),
|
|
|
+ fmt.Sprintf("%s=%d", "appId", appInfo.AppIdHash.IntVal),
|
|
|
+ fmt.Sprintf("%s=%d", "agentId", appInfo.AgentId),
|
|
|
+ fmt.Sprintf("%s=%d", "hostId", utils.GetIntHostID()),
|
|
|
+ fmt.Sprintf("%s=%d", "accountId", utils.GetAccountID()),
|
|
|
+ }
|
|
|
+ argkv := strings.Join(kvPairs, ",")
|
|
|
+ klog.Infof("[Jvm stack uprobe] params:[%s]", argkv)
|
|
|
+
|
|
|
+ args := []string{"load", "instrument", "false", argkv}
|
|
|
+ jattacher := jattach.JvmJattacher{
|
|
|
+ Pid: pid,
|
|
|
+ Args: args,
|
|
|
+ PrintOutput: 1,
|
|
|
+ }
|
|
|
+
|
|
|
+ res, err := jattacher.JAttach()
|
|
|
+ klog.Infof("[Jvm stack uprobe] JAttach Result: %d", res)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
//path = utils.GetDefaultAgentsPath("NativeAgent", "libnativeAgent.so")
|
|
|
- //path = "/tmp/NativeAgentSo2378900480034120722.tmp"
|
|
|
- path = utils.GetDefaultAgentsPath("NativeAgent", "libnativeAgent.so")
|
|
|
+ //tmp/NativeAgentSo2297066477572820801.tmp
|
|
|
+ path, err := FindNativeSoFromMapped(pid, "NativeAgentSo", ".tmp")
|
|
|
+ if err != nil {
|
|
|
+ klog.Error(err)
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
|
|
|
setNodeEnter := "Java_com_cloudwise_agent_common_natives_TraceNative_setNodeEnter"
|
|
|
setNodeReturn := "Java_com_cloudwise_agent_common_natives_TraceNative_setNodeReturn"
|
|
|
|
|
|
- klog.Infoln("Attach Start AttachJVMStackUprobes", path)
|
|
|
+ klog.Infoln("[Jvm stack uprobe] Attach Start AttachJVMStackUprobes", path)
|
|
|
|
|
|
var links []link.Link
|
|
|
ex, err := link.OpenExecutable(path)
|
|
|
if err != nil {
|
|
|
klog.Error(err)
|
|
|
- return nil
|
|
|
+ return nil, err
|
|
|
}
|
|
|
|
|
|
- klog.Infoln("Attach Start " + setNodeEnter)
|
|
|
- uplink, err := ex.Uprobe(setNodeEnter, t.uprobes["setNodeEnter"], &link.UprobeOptions{Offset: 0x0})
|
|
|
+ klog.Infof("[Jvm stack uprobe] Attach Start [%s] [%s] ", setNodeEnter, setNodeReturn)
|
|
|
+ uplink, err := ex.Uprobe(setNodeEnter, t.uprobes["setNodeEnter"], &link.UprobeOptions{Offset: 0x0, PID: int(pid)})
|
|
|
if err != nil {
|
|
|
- klog.Errorf("attaching ERROR: %v, %v, %v\n", err, setNodeEnter, uplink)
|
|
|
+ klog.Errorf("[Jvm stack uprobe] Attaching ERROR: %v, %v, %v\n", err, setNodeEnter, uplink)
|
|
|
+ return nil, err
|
|
|
} else {
|
|
|
links = append(links, uplink)
|
|
|
}
|
|
|
@@ -69,9 +110,39 @@ func (t *Tracer) AttachJVMStackUprobes(path string, uprobes []tracer.Uprobe) []l
|
|
|
klog.Infoln("Attach Start " + setNodeReturn)
|
|
|
uplink, err = ex.Uprobe(setNodeReturn, t.uprobes["setNodeReturn"], &link.UprobeOptions{Offset: 0x0})
|
|
|
if err != nil {
|
|
|
- klog.Errorf("attaching ERROR: %v, %v, %v\n", err, setNodeReturn, uplink)
|
|
|
+ klog.Errorf("[Jvm stack uprobe] Attaching ERROR: %v, %v, %v\n", err, setNodeReturn, uplink)
|
|
|
+ return nil, err
|
|
|
} else {
|
|
|
links = append(links, uplink)
|
|
|
}
|
|
|
- return links
|
|
|
+ return links, nil
|
|
|
+}
|
|
|
+
|
|
|
+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 {
|
|
|
+ return "", fmt.Errorf("error opening maps file: %v", err)
|
|
|
+ }
|
|
|
+ defer tmpFile.Close()
|
|
|
+
|
|
|
+ // 使用 bufio.Scanner 逐行读取文件内容
|
|
|
+ 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 // 返回路径
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if err = scanner.Err(); err != nil {
|
|
|
+ return "", fmt.Errorf("error reading maps file: %v", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ return "", fmt.Errorf("no matching path found")
|
|
|
}
|