1
0
mirror of https://github.com/google/gops.git synced 2024-11-24 08:22:25 +02:00

gops: concurrently lookup for Go processes

This commit is contained in:
Jaana Burcu Dogan 2017-01-19 16:30:38 -08:00
parent ad978d77e6
commit 290a9a1e3d

70
main.go
View File

@ -6,14 +6,15 @@
package main package main
import ( import (
"bytes"
"fmt" "fmt"
"log" "log"
"os" "os"
"strconv" "strconv"
"strings" "strings"
"sync"
"github.com/google/gops/internal/objfile" "github.com/google/gops/internal/objfile"
ps "github.com/keybase/go-ps" ps "github.com/keybase/go-ps"
) )
@ -72,57 +73,66 @@ func processes() {
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
var undetermined int
var wg sync.WaitGroup
wg.Add(len(pss))
for _, pr := range pss { for _, pr := range pss {
if pr.Pid() == 0 { pr := pr
// ignore system process go func() {
continue defer wg.Done()
}
path, err := pr.Path() printIfGo(pr)
if err != nil { }()
undetermined++
continue
}
ok, agent, err := isGo(pr.Pid(), path)
if err != nil {
// TODO(jbd): worth to report the number?
continue
}
if ok {
fmt.Printf("%d", pr.Pid())
if agent {
fmt.Printf("*")
}
fmt.Printf("\t%v\t(%v)\n", pr.Executable(), path)
}
}
if undetermined > 0 {
fmt.Printf("\n%d processes left undetermined\n", undetermined)
} }
wg.Wait()
} }
func isGo(pid int, path string) (ok bool, agent bool, err error) { // reportGo looks up the runtime.buildVersion symbol
// in the process' binary and determines if the process
// if a Go process or not. If the process is a Go process,
// it reports PID, binary name and full path of the binary.
func printIfGo(pr ps.Process) {
if pr.Pid() == 0 {
// ignore system process
return
}
path, err := pr.Path()
if err != nil {
return
}
obj, err := objfile.Open(path) obj, err := objfile.Open(path)
if err != nil { if err != nil {
return false, false, err return
} }
defer obj.Close() defer obj.Close()
symbols, err := obj.Symbols() symbols, err := obj.Symbols()
if err != nil { if err != nil {
return false, false, err return
} }
var ok bool
var agent bool
// TODO(jbd): find a faster way to determine Go programs. // TODO(jbd): find a faster way to determine Go programs.
for _, s := range symbols { for _, s := range symbols {
if s.Name == "runtime.buildVersion" { if s.Name == "runtime.buildVersion" {
ok = true ok = true
} }
// TODO(jbd): Stat the pid file to determine if the agent is still working.
if strings.HasPrefix(s.Name, "github.com/google/gops/agent") { if strings.HasPrefix(s.Name, "github.com/google/gops/agent") {
agent = true agent = true
} }
} }
return ok, agent, nil if ok {
buf := bytes.NewBuffer(nil)
fmt.Fprintf(buf, "%d", pr.Pid())
if agent {
fmt.Fprint(buf, "*")
}
fmt.Fprintf(buf, "\t%v\t(%v)\n", pr.Executable(), path)
buf.WriteTo(os.Stdout)
}
} }
func usage(msg string) { func usage(msg string) {