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:
parent
ad978d77e6
commit
290a9a1e3d
70
main.go
70
main.go
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user