Skip to content

Commit 8bdb235

Browse files
authored
fix process running check (#130)
Fix false positive process detection when an unrelated thread's id matches the old process id.
1 parent c09e482 commit 8bdb235

File tree

17 files changed

+944
-10
lines changed

17 files changed

+944
-10
lines changed

Gopkg.lock

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type: fix
2+
fix:
3+
description: Fix false positive process detection when an unrelated thread's id matches the old process id.
4+
links:
5+
- https://github.com/palantir/go-java-launcher/pull/130

init/cli/lib.go

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"strings"
2525
"syscall"
2626

27+
ps "github.com/mitchellh/go-ps"
2728
"github.com/palantir/pkg/cli"
2829
"github.com/pkg/errors"
2930

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

111-
if running, proc := isPidRunning(pid); running {
112+
running, proc, err := isPidRunning(pid)
113+
if err != nil {
114+
return nil, nil, err
115+
}
116+
if running {
112117
return &pid, proc, nil
113118
}
114119
return &pid, nil, nil
@@ -146,16 +151,37 @@ func getConfiguredCommands(ctx cli.Context, loggers launchlib.ServiceLoggers) (m
146151
return cmds, nil
147152
}
148153

149-
func isPidRunning(pid int) (bool, *os.Process) {
154+
func isPidRunning(pid int) (bool, *os.Process, error) {
150155
// Docs say FindProcess always succeeds on Unix.
151156
proc, _ := os.FindProcess(pid)
152-
if isProcRunning(proc) {
153-
return true, proc
157+
running, err := isProcRunning(proc)
158+
if err != nil {
159+
return false, nil, err
154160
}
155-
return false, nil
161+
if running {
162+
return true, proc, nil
163+
}
164+
return false, nil, nil
156165
}
157166

158-
func isProcRunning(proc *os.Process) bool {
167+
func isProcRunning(proc *os.Process) (bool, error) {
159168
// This is the way to check if a process exists: https://linux.die.net/man/2/kill.
160-
return proc.Signal(syscall.Signal(0)) == nil
169+
// On linux, this may respond true if there is a thread running with the same id.
170+
running := proc.Signal(syscall.Signal(0)) == nil
171+
if !running {
172+
return false, nil
173+
}
174+
175+
// On linux, iterating over processes will only return running processes. Unfortunately,
176+
// getting exactly the one pid will also return a thread of the same id.
177+
procs, err := ps.Processes()
178+
if err != nil {
179+
return false, err
180+
}
181+
for _, p := range procs {
182+
if p.Pid() == proc.Pid {
183+
return true, nil
184+
}
185+
}
186+
return false, nil
161187
}

init/cli/stop.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ func waitForServiceToStop(ctx cli.Context, procs map[string]*os.Process) error {
106106
select {
107107
case <-ticker.Chan():
108108
for name, remainingProc := range procs {
109-
if !isProcRunning(remainingProc) {
109+
running, err := isProcRunning(remainingProc)
110+
if err != nil {
111+
return err
112+
}
113+
if !running {
110114
delete(procs, name)
111115
}
112116
}
@@ -116,7 +120,11 @@ func waitForServiceToStop(ctx cli.Context, procs map[string]*os.Process) error {
116120
case <-timer.Chan():
117121
killedProcs := make([]string, 0, len(procs))
118122
for name, remainingProc := range procs {
119-
if isProcRunning(remainingProc) {
123+
running, err := isProcRunning(remainingProc)
124+
if err != nil {
125+
return err
126+
}
127+
if running {
120128
if err := remainingProc.Kill(); err != nil {
121129
// If this actually errors, something is probably seriously wrong.
122130
// Just stop immediately.

vendor/github.com/mitchellh/go-ps/.gitignore

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/mitchellh/go-ps/.travis.yml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/mitchellh/go-ps/LICENSE.md

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/mitchellh/go-ps/README.md

Lines changed: 34 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/mitchellh/go-ps/Vagrantfile

Lines changed: 43 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/mitchellh/go-ps/go.mod

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)