Skip to content

os/exec: command.Process.Kill() results in an invalid exit status code #7938

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gopherbot opened this issue May 5, 2014 · 3 comments
Closed

Comments

@gopherbot
Copy link
Contributor

by onsijoe:

What does 'go version' print?

go version go1.2.1 darwin/amd64

What steps reproduce the problem?

Here's a complete program that exhibits the problem (because it involves exec, it
doesn't manifest in the playground):

package main

import (
    "fmt"
    "os/exec"
    "syscall"
)

func main() {
    cmd := exec.Command("sleep", "1000000")
    cmd.Start()

    done := make(chan struct{})
    go func() {
        err := cmd.Wait()
        exitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()

        fmt.Println("Error:", err)
        fmt.Println("Status:", exitStatus)

        close(done)
    }()

    cmd.Process.Kill()

    <-done
}


What happened?
The output is

Error: signal: killed
Status: -1

What should have happened instead?

Instead, I (believe) I should have seen:

Error: signal: killed
Status: 137

Please provide any additional information below.

Looking at ExitStatus here
(http://golang.org/src/pkg/syscall/syscall_linux.go?s=4510:4546#L180) I see that -1
implies the process has not exited.  But it actually has (I checked with `ps`)!

Is this a bug, or desired behavior?  When I run `sleep 1000000` in a shell and then send
said process the KILL signal I get an exit code of 137 which is consistent with
http://www.tldp.org/LDP/abs/html/exitcodes.html
@gopherbot
Copy link
Contributor Author

Comment 1 by onsijoe:

FWIW also happens on the 1.3 beta:
go version devel +f8b50ad4cac4 Mon Apr 21 17:00:27 2014 -0700 + darwin/amd64

@ianlancetaylor
Copy link
Contributor

Comment 2:

You have to checked Signaled to see whether the process exited because of a signal. 
This is a direct reflection of the way that Unix wait status work in Go.
package main
import (
    "fmt"
    "os/exec"
    "syscall"
)
func main() {
    cmd := exec.Command("sleep", "1000000")
    cmd.Start()
    done := make(chan struct{})
    go func() {
        err := cmd.Wait()
        status := cmd.ProcessState.Sys().(syscall.WaitStatus)
        exitStatus := status.ExitStatus()
        signaled := status.Signaled()
        signal := status.Signal()
        fmt.Println("Error:", err)
        if signaled {
            fmt.Println("Signal:", signal)
        } else {
            fmt.Println("Status:", exitStatus)
        }
        close(done)
    }()
    cmd.Process.Kill()
    <-done
}

Status changed to WorkingAsIntended.

@gopherbot
Copy link
Contributor Author

Comment 3 by onsi@pivotallabs.com:

Makes sense, thanks!

@golang golang locked and limited conversation to collaborators Jun 25, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants