| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- 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
- ex, err := link.OpenExecutable(path)
- if err != nil {
- return nil
- }
- klog.Infoln("[stack] Attach Start", path)
- for i, up := range uprobes {
- klog.Debugf("[stack] attaching %d -> %d -> %s -> 0x%x -> 0x%x -> 0x%x", i, len(uprobes), up.Funcname, up.AbsOffset, up.Address, up.AbsOffset+up.Address)
- var prog *ebpf.Program
- switch up.Location {
- case tracer.AtEntry:
- prog = t.uprobes["ent"]
- case tracer.AtRet:
- prog = t.uprobes["ret"]
- case tracer.AtDotNetEntry:
- prog = t.uprobes["dotnetent"]
- }
- uplink, err := ex.Uprobe(up.Funcname, prog, &link.UprobeOptions{Address: up.Address, Offset: up.AbsOffset})
- if err != nil {
- klog.Errorf("[stack] attachingERROR:%v, %v, %v", err, up, uplink)
- // return nil
- } else {
- links = append(links, uplink)
- }
- }
- return links
- }
- // 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")
- //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("[Jvm stack uprobe] Attach Start AttachJVMStackUprobes", path)
- var links []link.Link
- ex, err := link.OpenExecutable(path)
- if err != nil {
- klog.Error(err)
- return nil, err
- }
- 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("[Jvm stack uprobe] Attaching ERROR: %v, %v, %v\n", err, setNodeEnter, uplink)
- return nil, err
- } else {
- links = append(links, uplink)
- }
- klog.Infoln("Attach Start " + setNodeReturn)
- uplink, err = ex.Uprobe(setNodeReturn, t.uprobes["setNodeReturn"], &link.UprobeOptions{Offset: 0x0})
- if err != nil {
- klog.Errorf("[Jvm stack uprobe] Attaching ERROR: %v, %v, %v\n", err, setNodeReturn, uplink)
- return nil, err
- } else {
- links = append(links, uplink)
- }
- 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")
- }
|