Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions containers/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -1238,13 +1238,17 @@ func (c *Container) attachTlsUprobes(tracer *ebpftracer.Tracer, pid uint32) {
return
}
if !p.openSslUprobesChecked {
p.uprobes = append(p.uprobes, tracer.AttachOpenSslUprobes(pid)...)
if key := tracer.AttachOpenSslUprobes(pid); key != nil {
p.uprobeKeys = append(p.uprobeKeys, *key)
}
p.openSslUprobesChecked = true
}
if !p.goTlsUprobesChecked {
uprobes, isGolangApp := tracer.AttachGoTlsUprobes(pid)
key, isGolangApp := tracer.AttachGoTlsUprobes(pid)
p.isGolangApp = isGolangApp
p.uprobes = append(p.uprobes, uprobes...)
if key != nil {
p.uprobeKeys = append(p.uprobeKeys, *key)
}
p.goTlsUprobesChecked = true
}
}
Expand Down
29 changes: 14 additions & 15 deletions containers/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"os"
"time"

"github.com/cilium/ebpf/link"
"github.com/coroot/coroot-node-agent/ebpftracer"
"github.com/coroot/coroot-node-agent/gpu"
"github.com/coroot/coroot-node-agent/proc"
Expand Down Expand Up @@ -35,10 +34,11 @@ type Process struct {
ctx context.Context
cancelFunc context.CancelFunc

tracer *ebpftracer.Tracer
dotNetMonitor *DotNetMonitor
isGolangApp bool

uprobes []link.Link
uprobeKeys []ebpftracer.UprobeKey
goTlsUprobesChecked bool
openSslUprobesChecked bool
pythonGilChecked bool
Expand All @@ -50,7 +50,7 @@ type Process struct {
}

func NewProcess(pid uint32, stats *taskstats.Stats, tracer *ebpftracer.Tracer) *Process {
p := &Process{Pid: pid, StartedAt: stats.BeginTime}
p := &Process{Pid: pid, StartedAt: stats.BeginTime, tracer: tracer}
p.Flags, _ = proc.GetFlags(pid)
p.ctx, p.cancelFunc = context.WithCancel(context.Background())
go p.instrument(tracer)
Expand Down Expand Up @@ -118,8 +118,10 @@ func (p *Process) instrumentPython(cmdline []byte, tracer *ebpftracer.Tracer) {
if !pythonCmd.Match(cmd) {
return
}
p.pythonPrevStats = &ebpftracer.PythonStats{}
p.uprobes = append(p.uprobes, tracer.AttachPythonThreadLockProbes(p.Pid)...)
if key := tracer.AttachPythonThreadLockProbes(p.Pid); key != nil {
p.pythonPrevStats = &ebpftracer.PythonStats{}
p.uprobeKeys = append(p.uprobeKeys, *key)
}
}

func (p *Process) instrumentNodejs(exe string, tracer *ebpftracer.Tracer) {
Expand All @@ -130,8 +132,10 @@ func (p *Process) instrumentNodejs(exe string, tracer *ebpftracer.Tracer) {
if !nodejsCmd.MatchString(exe) {
return
}
p.nodejsPrevStats = &ebpftracer.NodejsStats{}
p.uprobes = append(p.uprobes, tracer.AttachNodejsProbes(p.Pid, exe)...)
if key := tracer.AttachNodejsProbes(p.Pid, exe); key != nil {
p.nodejsPrevStats = &ebpftracer.NodejsStats{}
p.uprobeKeys = append(p.uprobeKeys, *key)
}
}

func (p *Process) addGpuUsageSample(sample gpu.ProcessUsageSample) {
Expand Down Expand Up @@ -173,13 +177,8 @@ func (p *Process) removeOldGpuUsageSamples(cutoff time.Time) {

func (p *Process) Close() {
p.cancelFunc()
if len(p.uprobes) > 0 {
uprobes := p.uprobes
p.uprobes = nil
go func() {
for _, u := range uprobes {
_ = u.Close()
}
}()
if len(p.uprobeKeys) > 0 {
p.tracer.ReleaseGlobalUprobes(p.uprobeKeys)
p.uprobeKeys = nil
}
}
24 changes: 15 additions & 9 deletions ebpftracer/nodejs.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"k8s.io/klog/v2"
)

func (t *Tracer) AttachNodejsProbes(pid uint32, exe string) []link.Link {
func (t *Tracer) AttachNodejsProbes(pid uint32, exe string) *UprobeKey {
log := func(libPath, msg string, err error) {
if err != nil {
for _, s := range []string{"no such file or directory", "no such process", "permission denied"} {
Expand All @@ -26,17 +26,23 @@ func (t *Tracer) AttachNodejsProbes(pid uint32, exe string) []link.Link {
}

for _, libPath := range append(getLibuv(pid), proc.Path(pid, "root", exe)) {
if links, err := t.attachNodejsUprobes(libPath, pid); err == nil {
key, ok := t.AcquireGlobalUprobe(libPath, func() []link.Link {
links, err := t.attachNodejsUprobes(libPath)
if err != nil {
log(libPath, "failed to attach nodejs uprobes", err)
return nil
}
log(libPath, "nodejs uprobes attached", nil)
return links
} else {
log(libPath, "failed to attach nodejs uprobes", err)
})
if ok {
return &key
}
}
return nil
}

func (t *Tracer) attachNodejsUprobes(libPath string, pid uint32) ([]link.Link, error) {
func (t *Tracer) attachNodejsUprobes(libPath string) ([]link.Link, error) {
exe, err := link.OpenExecutable(libPath)
if err != nil {
return nil, err
Expand All @@ -51,14 +57,14 @@ func (t *Tracer) attachNodejsUprobes(libPath string, pid uint32) ([]link.Link, e
if err != nil {
return nil, err
}
l, err := s.AttachUprobe(exe, t.uprobes["uv_io_poll_enter"], pid)
l, err := s.AttachUprobe(exe, t.uprobes["uv_io_poll_enter"], 0)
if err != nil {
return nil, err
}
var links []link.Link
links = append(links, l)

ls, err := s.AttachUretprobes(exe, t.uprobes["uv_io_poll_exit"], pid)
ls, err := s.AttachUretprobes(exe, t.uprobes["uv_io_poll_exit"], 0)
links = append(links, ls...)
if err != nil {
for _, l := range links {
Expand All @@ -72,12 +78,12 @@ func (t *Tracer) attachNodejsUprobes(libPath string, pid uint32) ([]link.Link, e
if err != nil {
break
}
l, err = s.AttachUprobe(exe, t.uprobes["uv_io_cb_enter"], pid)
l, err = s.AttachUprobe(exe, t.uprobes["uv_io_cb_enter"], 0)
if err != nil {
break
}
links = append(links, l)
ls, err = s.AttachUretprobes(exe, t.uprobes["uv_io_cb_exit"], pid)
ls, err = s.AttachUretprobes(exe, t.uprobes["uv_io_cb_exit"], 0)
links = append(links, ls...)
if err != nil {
break
Expand Down
30 changes: 14 additions & 16 deletions ebpftracer/python.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var (
muslRegexp = regexp.MustCompile(`ld-musl[\.-]`)
)

func (t *Tracer) AttachPythonThreadLockProbes(pid uint32) []link.Link {
func (t *Tracer) AttachPythonThreadLockProbes(pid uint32) *UprobeKey {
log := func(libPath, msg string, err error) {
if err != nil {
for _, s := range []string{"no such file or directory", "no such process", "permission denied"} {
Expand All @@ -31,26 +31,24 @@ func (t *Tracer) AttachPythonThreadLockProbes(pid uint32) []link.Link {
klog.InfofDepth(1, "pid=%d lib=%s: %s", pid, libPath, msg)
}

var (
links []link.Link
err error
)

for _, libPath := range getPthreadLibs(pid) {
if links, err = t.attachPythonUprobes(libPath, pid); err == nil {
key, ok := t.AcquireGlobalUprobe(libPath, func() []link.Link {
links, err := t.attachPythonUprobes(libPath)
if err != nil {
log(libPath, "failed to attach python uprobes", err)
return nil
}
log(libPath, "python uprobes attached", nil)
return links
} else {
log(libPath, "failed to attach python uprobes", err)
})
if ok {
return &key
}
}
if len(links) > 0 {

}
return links
return nil
}

func (t *Tracer) attachPythonUprobes(libPath string, pid uint32) ([]link.Link, error) {
func (t *Tracer) attachPythonUprobes(libPath string) ([]link.Link, error) {
exe, err := link.OpenExecutable(libPath)
if err != nil {
return nil, err
Expand All @@ -65,12 +63,12 @@ func (t *Tracer) attachPythonUprobes(libPath string, pid uint32) ([]link.Link, e
if err != nil {
return nil, err
}
l, err := s.AttachUprobe(exe, t.uprobes["pthread_cond_timedwait_enter"], pid)
l, err := s.AttachUprobe(exe, t.uprobes["pthread_cond_timedwait_enter"], 0)
if err != nil {
return nil, err
}
links := []link.Link{l}
ls, err := s.AttachUretprobes(exe, t.uprobes["pthread_cond_timedwait_exit"], pid)
ls, err := s.AttachUretprobes(exe, t.uprobes["pthread_cond_timedwait_exit"], 0)
links = append(links, ls...)
if err != nil {
for _, l := range links {
Expand Down
Loading
Loading