shirou / gopsutil

psutil for golang
Other
10.36k stars 1.57k forks source link

[invoker] set the `WaitDelay` to avoid getting indefinitely blocking wait() #1614

Closed acabarbaye closed 1 month ago

acabarbaye commented 4 months ago

Describe the bug

The problem lies in how the commands are spawned in the Invoker https://github.com/shirou/gopsutil/blob/6100124c96d37a9282ca4bf158db8a743e475077/internal/common/common.go#L50 if the spawned command opens I/Os, the wait() could block indefinitely. This bug has been reported in many issues with go : https://github.com/golang/go/issues/24050 https://github.com/golang/go/issues/20730 https://github.com/golang/go/issues/23019 https://github.com/golang/go/issues/56187 https://github.com/golang/go/issues/57129 https://github.com/golang/go/issues/60309 https://github.com/golang/go/issues/22485

A solution is to set the WaitDelay to ensure wait() returns

// If WaitDelay is non-zero, the command's I/O pipes will be closed after
// WaitDelay has elapsed after either the command's process has exited or
// (if Context is non-nil) Context is done, whichever occurs first.
// If the command's process is still running after WaitDelay has elapsed,
// it will be terminated with os.Kill before the pipes are closed.
//
// If the command exits with a success code after pipes are closed due to
// WaitDelay and no Interrupt signal has been sent, Wait and similar methods
// will return ErrWaitDelay instead of nil.
//
// If WaitDelay is zero (the default), I/O pipes will be read until EOF,
// which might not occur until orphaned subprocesses of the command have
// also closed their descriptors for the pipes.
WaitDelay time.Duration

To Reproduce the following should block indefinitely

common.Invoke{}.Command("bash", "-c", "watch date > date.txt 2>&1")

Expected behavior The command above should be terminated if the Timeout is exceeded

Environment (please complete the following information):

Additional context [Cross-compiling? Paste the command you are using to cross-compile and the result of the corresponding go env]

shirou commented 4 months ago

That is why we introduced xxxWithContext. We can avoid waiting indefinitely by setting a timeout for a context . Further, as the author of the library, we cannot set the appropriate wait time. Therefore, we provide a way for library users to set a timeout.

shirou commented 1 month ago

Close for not updating. Feel free to reopen if you have more questions.