Skip to content

Exiting 0 on SIGTERM makes a kill indistinguishable from a clean shutdown #119

Description

@setkyar

Split out of #112 (secondary finding 3), which was closed by #113 — that PR only addressed the restart storm. Reported by @laulpogan.

Problem

internal/app/app.go:198 uses signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) and the process then returns from Main normally. A SIGTERM kill is therefore indistinguishable from a voluntary shutdown in every signal available to an operator:

  • launchd reports last exit code = 0 — identical to "user stopped it".
  • A wait-based supervisor sees status 0 and logs a voluntary exit.

Why it matters

This is what made #112 take hours to diagnose. The restart storm was hundreds of SIGTERM kills from launchctl kickstart -k, and every external signal said "clean exit", sending the reporter through launchd environment, stdin EOF, ThrottleInterval, plist churn, and bind conflicts before the actual cause. The storm itself is fixed, but the diagnostic gap will cost the next person the same time for any other kill source.

Options

  • Log the shutdown cause: shutting down: received SIGTERM.
  • And/or exit 143 (128+15) so last exit code carries the information. Note SIGTERM from systemctl stop / launchctl stop then becomes a documented, expected non-zero — worth a docs note if that tradeoff is unwanted, in which case the supervisor-visible cause string alone is the alternative.

For contrast, the state-file lock path already gets this right: internal/app/state_file.go plus state_file_unix.go's non-blocking flock exit 1 with an accurate, actionable message. The shutdown path is missing that same distinguishability.

Verified against current main (1040251).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions