Skip to content
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

glog: check that stderr is valid before using it by default #72

Merged
merged 1 commit into from
Nov 4, 2024

Conversation

chressie
Copy link
Contributor

@chressie chressie commented Nov 4, 2024

Windows Services are spawned without stdout and stderr, so any attempt to use them equates to referencing an invalid file Handle. stderrSink returns the error, which makes logsink trigger the termination of the process. The result is that any call to log.Error (or log.Fatal) from a Windows Service will always crash the program.

This approach checks that os.Stderr's embedded file descriptor (Handle, for Windows) is non-NULL once during init to determine its validity and if it fails, then never registers stderrSink as a logsink.

Disabling based upon whether os.Stderr is NULL was chosen because it's precise, doesn't actually influence the result of any output and doesn't require any syscalls, but still detects the case in which stderr is unavailable on Windows.

A rejected approach here would've been to swallow the errors from stderrSink.Emit, thus sparing us program termination at the hands of logsink. I rejected this approach because it felt like it could result in some subtle behavioral changes. For example, invoking log.Error after os.Stderr.Close() would no longer exit the program and that felt like a non-trivial change (although I can think of no reason why one would desire this behavior).

cl/680817112 (google-internal)

Windows Services are [spawned without `stdout` and `stderr`](https://learn.microsoft.com/en-us/windows/console/getstdhandle#return-value:~:text=If%20an%20application%20does%20not%20have%20associated%20standard%20handles%2C%20such%20as%20a%20service%20running%20on%20an%20interactive%20desktop%2C%20and%20has%20not%20redirected%20them%2C%20the%20return%20value%20is%20NULL.), so any attempt to use them equates to referencing an invalid file `Handle`. `stderrSink` returns the error, which makes `logsink` trigger the termination of the process. The result is that any call to `log.Error` (or `log.Fatal`) from a Windows Service will always crash the program.

This approach checks that `os.Stderr`'s embedded file descriptor (`Handle`, for Windows) is non-NULL once during `init` to determine its validity and if it fails, then never registers `stderrSink` as a logsink.

Disabling based upon whether `os.Stderr` is NULL was chosen because it's precise, doesn't actually influence the result of any output and doesn't require any syscalls, but still detects the case in which `stderr` is unavailable on Windows.

A rejected approach here would've been to swallow the errors from `stderrSink.Emit`, thus sparing us program termination at the hands of `logsink`. I rejected this approach because it felt like it could result in some subtle behavioral changes. For example, invoking `log.Error` after `os.Stderr.Close()` would no longer exit the program and that felt like a non-trivial change (although I can think of no reason why one would desire this behavior).

cl/680817112 (google-internal)
@chressie chressie assigned chressie and stapelberg and unassigned chressie Nov 4, 2024
@stapelberg stapelberg merged commit 459cf3b into golang:master Nov 4, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants