go-delve_delve/pkg/proc/debuginfod/debuginfod.go
Alessandro Arzilli 17acdb87a7
proc,service,terminal: add events call use it for dld notifications (#3980)
Add a GetEvents method that can be used to retrieve debug events, adds
events for downloading debug info through debuginfod and shows those
events in the command line client as well as console messages in DAP.

In the future this events mechanism can be used to unify EBPF
tracepoints with old style tracepoints.

Update #3906
2025-08-04 08:12:48 -07:00

68 lines
1.5 KiB
Go

package debuginfod
import (
"bufio"
"bytes"
"os"
"os/exec"
"strings"
"time"
)
const debuginfodFind = "debuginfod-find"
const notificationThrottle time.Duration = 1 * time.Second
func execFind(notify func(string), args ...string) (string, error) {
if _, err := exec.LookPath(debuginfodFind); err != nil {
return "", err
}
cmd := exec.Command(debuginfodFind, args...)
if notify != nil {
cmd.Env = append(os.Environ(), "DEBUGINFOD_PROGRESS=yes")
stderr, err := cmd.StderrPipe()
if err != nil {
return "", err
}
s := bufio.NewScanner(stderr)
s.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.IndexAny(data, "\n\r"); i >= 0 {
return i + 1, dropCR(data[0:i]), nil
}
if atEOF {
return len(data), dropCR(data), nil
}
return 0, nil, nil
})
go func() {
var tlast time.Time
for s.Scan() {
if time.Since(tlast) > notificationThrottle {
tlast = time.Now()
notify(string(s.Text()))
}
}
}()
}
out, err := cmd.Output() // ignore stderr
if err != nil {
return "", err
}
return strings.TrimSpace(string(out)), err
}
func dropCR(data []byte) []byte {
r, _ := bytes.CutSuffix(data, []byte{'\r'})
return r
}
func GetSource(buildid, filename string) (string, error) {
return execFind(nil, "source", buildid, filename)
}
func GetDebuginfo(notify func(string), buildid string) (string, error) {
return execFind(notify, "debuginfo", buildid)
}