in pkg/profiling/task/offcpu/runner.go [97:147]
func (r *Runner) Run(ctx context.Context, notify base.ProfilingRunningSuccessNotify) error {
objs := bpfObjects{}
spec, err := loadBpf()
if err != nil {
return err
}
// update the monitor pid
funcName := "do_finish_task_switch"
replacedPid := false
for i, ins := range spec.Programs[funcName].Instructions {
if ins.Reference() == "MONITOR_PID" {
spec.Programs[funcName].Instructions[i].Constant = int64(r.pid)
spec.Programs[funcName].Instructions[i].Offset = 0
replacedPid = true
}
}
if !replacedPid {
return fmt.Errorf("replace the monitor pid failure")
}
if err1 := spec.LoadAndAssign(&objs, btf.GetEBPFCollectionOptionsIfNeed(spec)); err1 != nil {
return err1
}
r.bpf = &objs
symbols := r.findMatchesSymbol()
linker := btf.NewLinker()
linkedCount := 0
for _, symbol := range symbols {
switchers := make(map[string]*ebpf.Program)
switchers[symbol] = objs.DoFinishTaskSwitch
err = linker.AddLinkOrError(link.Kprobe, switchers)
if err != nil {
log.Warnf("link to finish task swtich(%s) failure: %v", symbol, err)
continue
}
linkedCount++
}
if linkedCount == 0 {
return fmt.Errorf("link to finish task swtich failure: no symbol linked")
}
if err := linker.HasError(); err != nil {
return fmt.Errorf("link to finish task swtich failure: %v", err)
}
r.kprobe = linker
notify()
<-r.stopChan
return nil
}