Skip to content

Commit

Permalink
fix process running check (#130)
Browse files Browse the repository at this point in the history
Fix false positive process detection when an unrelated thread's id matches the old process id.
  • Loading branch information
rzpt authored Jun 9, 2020
1 parent c09e482 commit 8bdb235
Show file tree
Hide file tree
Showing 17 changed files with 944 additions and 10 deletions.
8 changes: 7 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions changelog/@unreleased/pr-130.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type: fix
fix:
description: Fix false positive process detection when an unrelated thread's id matches the old process id.
links:
- https://github.com/palantir/go-java-launcher/pull/130
40 changes: 33 additions & 7 deletions init/cli/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"strings"
"syscall"

ps "github.com/mitchellh/go-ps"
"github.com/palantir/pkg/cli"
"github.com/pkg/errors"

Expand Down Expand Up @@ -108,7 +109,11 @@ func getCmdProcess(name string) (*int, *os.Process, error) {
return nil, nil, errors.Wrap(err, "pid file did not contain an integer")
}

if running, proc := isPidRunning(pid); running {
running, proc, err := isPidRunning(pid)
if err != nil {
return nil, nil, err
}
if running {
return &pid, proc, nil
}
return &pid, nil, nil
Expand Down Expand Up @@ -146,16 +151,37 @@ func getConfiguredCommands(ctx cli.Context, loggers launchlib.ServiceLoggers) (m
return cmds, nil
}

func isPidRunning(pid int) (bool, *os.Process) {
func isPidRunning(pid int) (bool, *os.Process, error) {
// Docs say FindProcess always succeeds on Unix.
proc, _ := os.FindProcess(pid)
if isProcRunning(proc) {
return true, proc
running, err := isProcRunning(proc)
if err != nil {
return false, nil, err
}
return false, nil
if running {
return true, proc, nil
}
return false, nil, nil
}

func isProcRunning(proc *os.Process) bool {
func isProcRunning(proc *os.Process) (bool, error) {
// This is the way to check if a process exists: https://linux.die.net/man/2/kill.
return proc.Signal(syscall.Signal(0)) == nil
// On linux, this may respond true if there is a thread running with the same id.
running := proc.Signal(syscall.Signal(0)) == nil
if !running {
return false, nil
}

// On linux, iterating over processes will only return running processes. Unfortunately,
// getting exactly the one pid will also return a thread of the same id.
procs, err := ps.Processes()
if err != nil {
return false, err
}
for _, p := range procs {
if p.Pid() == proc.Pid {
return true, nil
}
}
return false, nil
}
12 changes: 10 additions & 2 deletions init/cli/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,11 @@ func waitForServiceToStop(ctx cli.Context, procs map[string]*os.Process) error {
select {
case <-ticker.Chan():
for name, remainingProc := range procs {
if !isProcRunning(remainingProc) {
running, err := isProcRunning(remainingProc)
if err != nil {
return err
}
if !running {
delete(procs, name)
}
}
Expand All @@ -116,7 +120,11 @@ func waitForServiceToStop(ctx cli.Context, procs map[string]*os.Process) error {
case <-timer.Chan():
killedProcs := make([]string, 0, len(procs))
for name, remainingProc := range procs {
if isProcRunning(remainingProc) {
running, err := isProcRunning(remainingProc)
if err != nil {
return err
}
if running {
if err := remainingProc.Kill(); err != nil {
// If this actually errors, something is probably seriously wrong.
// Just stop immediately.
Expand Down
1 change: 1 addition & 0 deletions vendor/github.com/mitchellh/go-ps/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions vendor/github.com/mitchellh/go-ps/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions vendor/github.com/mitchellh/go-ps/LICENSE.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions vendor/github.com/mitchellh/go-ps/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions vendor/github.com/mitchellh/go-ps/Vagrantfile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions vendor/github.com/mitchellh/go-ps/go.mod

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions vendor/github.com/mitchellh/go-ps/process.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8bdb235

Please sign in to comment.