|
@@ -5,6 +5,7 @@ import (
|
|
|
"debug/elf"
|
|
"debug/elf"
|
|
|
debugelf "debug/elf"
|
|
debugelf "debug/elf"
|
|
|
"fmt"
|
|
"fmt"
|
|
|
|
|
+ "github.com/coroot/coroot-node-agent/common"
|
|
|
"io"
|
|
"io"
|
|
|
"log"
|
|
"log"
|
|
|
"os"
|
|
"os"
|
|
@@ -27,11 +28,12 @@ type uprobesDef struct {
|
|
|
RetAddress uint64
|
|
RetAddress uint64
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (c *Container) stackTrace(tracer *ebpftracer.Tracer, pid uint32) error {
|
|
|
|
|
|
|
+func (c *Container) StackTrace(tracer *ebpftracer.Tracer, pid uint32) error {
|
|
|
// 禁用stack
|
|
// 禁用stack
|
|
|
if tracer.DisableStackTracing() {
|
|
if tracer.DisableStackTracing() {
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
+ // 进程过滤
|
|
|
ENV_PID := os.Getenv("FILTER_PID")
|
|
ENV_PID := os.Getenv("FILTER_PID")
|
|
|
if ENV_PID != "" {
|
|
if ENV_PID != "" {
|
|
|
filterPid, _ := strconv.ParseInt(ENV_PID, 10, 64)
|
|
filterPid, _ := strconv.ParseInt(ENV_PID, 10, 64)
|
|
@@ -39,14 +41,24 @@ func (c *Container) stackTrace(tracer *ebpftracer.Tracer, pid uint32) error {
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ // 类型过滤
|
|
|
codeType := c.GetCodeTypeFromCache(pid)
|
|
codeType := c.GetCodeTypeFromCache(pid)
|
|
|
- if codeType.IsUnknownCode() || codeType.IsJvmCode() {
|
|
|
|
|
|
|
+ if codeType.IsUnknownCode() {
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ switch codeType {
|
|
|
|
|
+ case common.CodeTypeJava:
|
|
|
|
|
+ return c.jvmStackTrace(tracer, pid)
|
|
|
|
|
+ default:
|
|
|
|
|
+ return c.stackTrace(tracer, pid)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (c *Container) stackTrace(tracer *ebpftracer.Tracer, pid uint32) error {
|
|
|
p := c.processes[pid]
|
|
p := c.processes[pid]
|
|
|
if p == nil {
|
|
if p == nil {
|
|
|
- return nil
|
|
|
|
|
|
|
+ return fmt.Errorf("unknown process %d", pid)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if p.stackUprobesChecked {
|
|
if p.stackUprobesChecked {
|
|
@@ -75,10 +87,15 @@ func (c *Container) stackTrace(tracer *ebpftracer.Tracer, pid uint32) error {
|
|
|
fmt.Println("UprobesMatchString:::init", MatchString)
|
|
fmt.Println("UprobesMatchString:::init", MatchString)
|
|
|
path := proc.Path(uint32(pid), "exe")
|
|
path := proc.Path(uint32(pid), "exe")
|
|
|
|
|
|
|
|
|
|
+ var err error
|
|
|
if dbgpath != "" {
|
|
if dbgpath != "" {
|
|
|
- c.Uprobes, _ = c.getJavaAOTUprobes(binType, path, dbgpath, MatchString)
|
|
|
|
|
|
|
+ c.Uprobes, err = c.getJavaAOTUprobes(binType, path, dbgpath, MatchString)
|
|
|
} else {
|
|
} else {
|
|
|
- c.Uprobes, _ = c.getUprobes(path, MatchString)
|
|
|
|
|
|
|
+ c.Uprobes, err = c.getUprobes(path, MatchString)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
c.UprobesMap = map[string]tracerelf.Uprobe{}
|
|
c.UprobesMap = map[string]tracerelf.Uprobe{}
|
|
@@ -113,7 +130,9 @@ func (c *Container) getJavaAOTUprobes(binType, path string, dbgpath string, Matc
|
|
|
uprobes := []tracer.Uprobe{}
|
|
uprobes := []tracer.Uprobe{}
|
|
|
|
|
|
|
|
elfFile, err := elf.Open(path)
|
|
elfFile, err := elf.Open(path)
|
|
|
-
|
|
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
funSection := ".text"
|
|
funSection := ".text"
|
|
|
|
|
|
|
|
if binType == "dotnet" {
|
|
if binType == "dotnet" {
|
|
@@ -128,19 +147,19 @@ func (c *Container) getJavaAOTUprobes(binType, path string, dbgpath string, Matc
|
|
|
textSectionData, err := textSection.Data()
|
|
textSectionData, err := textSection.Data()
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
fmt.Println("failed to read text section", err)
|
|
fmt.Println("failed to read text section", err)
|
|
|
- return nil, nil
|
|
|
|
|
|
|
+ return nil, err
|
|
|
}
|
|
}
|
|
|
textSectionLen := uint64(len(textSectionData) - 1)
|
|
textSectionLen := uint64(len(textSectionData) - 1)
|
|
|
|
|
|
|
|
dwarfFile, err := elf.Open(dbgpath)
|
|
dwarfFile, err := elf.Open(dbgpath)
|
|
|
|
|
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatal(err)
|
|
|
|
|
|
|
+ return nil, err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
dwarfData, err := dwarfFile.DWARF()
|
|
dwarfData, err := dwarfFile.DWARF()
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatal(err)
|
|
|
|
|
|
|
+ return nil, err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
entryReader := dwarfData.Reader()
|
|
entryReader := dwarfData.Reader()
|
|
@@ -272,10 +291,15 @@ func (c *Container) getUprobes(path string, MatchString string) ([]tracer.Uprobe
|
|
|
|
|
|
|
|
// cache := map[string]interface{}{}
|
|
// cache := map[string]interface{}{}
|
|
|
// 解析 elf 文件
|
|
// 解析 elf 文件
|
|
|
- elfFile, _ := debugelf.NewFile(binFile)
|
|
|
|
|
|
|
+ elfFile, err := debugelf.NewFile(binFile)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
// 获取所有符号表
|
|
// 获取所有符号表
|
|
|
- symbols, _ := elfFile.Symbols()
|
|
|
|
|
-
|
|
|
|
|
|
|
+ symbols, err := elfFile.Symbols()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
sort.Slice(symbols, func(i, j int) bool { return symbols[i].Value < symbols[j].Value })
|
|
sort.Slice(symbols, func(i, j int) bool { return symbols[i].Value < symbols[j].Value })
|
|
|
|
|
|
|
|
c.Symbols = symbols
|
|
c.Symbols = symbols
|
|
@@ -309,7 +333,7 @@ func (c *Container) getUprobes(path string, MatchString string) ([]tracer.Uprobe
|
|
|
// found, err := regexp.MatchString("main.*", symbol.Name)
|
|
// found, err := regexp.MatchString("main.*", symbol.Name)
|
|
|
|
|
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- log.Fatal(err)
|
|
|
|
|
|
|
+ fmt.Println(err)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if found {
|
|
if found {
|