Skip to content

fix: detect parent death by ppid change instead of ppid==1#77

Merged
ErikBjare merged 1 commit into
ActivityWatch:masterfrom
TimeToBuildBob:fix/ppid-check-launchd-systemd
Feb 27, 2026
Merged

fix: detect parent death by ppid change instead of ppid==1#77
ErikBjare merged 1 commit into
ActivityWatch:masterfrom
TimeToBuildBob:fix/ppid-check-launchd-systemd

Conversation

@TimeToBuildBob

@TimeToBuildBob TimeToBuildBob commented Feb 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes the false-positive "parent process died" exit when aw-watcher-afk is run via:

  • macOS launchd (PID 1 is the legitimate parent)
  • Linux systemd user services (PID 1 is the legitimate parent)

The previous check os.getppid() == 1 assumed PID 1 always means orphaned/reparented to init. This is wrong for modern process managers where PID 1 IS the expected parent.

Fix: Store the initial parent PID at startup, then check if it changed — correctly detecting orphaned processes regardless of the init system.

Also improves the log message to show both old and new ppid for easier debugging.

Fixes #67

Test plan

  • Verify aw-watcher-afk runs correctly when launched by launchd on macOS
  • Verify aw-watcher-afk runs correctly as a systemd user service on Linux
  • Verify orphan detection still works (kill parent process, check watcher exits)

Important

Fix false-positive parent death detection in AFKWatcher by checking ppid change instead of ppid == 1.

  • Behavior:
    • Change parent death detection in AFKWatcher from os.getppid() == 1 to os.getppid() != self._initial_ppid in heartbeat_loop().
    • Store initial ppid at startup in AFKWatcher.__init__() for comparison.
    • Improve log message to show old and new ppid in heartbeat_loop().
  • Test Plan:
    • Verify aw-watcher-afk runs correctly with launchd on macOS and as a systemd user service on Linux.
    • Verify orphan detection by killing the parent process and checking if the watcher exits.

This description was created by Ellipsis for 7144da2. You can customize this summary. It will automatically update as commits are pushed.

The previous check `os.getppid() == 1` assumed that PID 1 always means
the parent died and the process was reparented to init. This fails when
aw-watcher-afk is legitimately launched by a PID 1 process:

- macOS: launchd (PID 1) as the launchd agent parent
- Linux: systemd (PID 1) as the systemd user service parent

The fix stores the initial parent PID at startup and checks if it
changed, which correctly detects orphaned processes regardless of the
init system or process manager.

Fixes ActivityWatch#67

@ellipsis-dev ellipsis-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed everything up to 7144da2 in 8 seconds. Click for details.
  • Reviewed 31 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 0 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.

Workflow ID: wflow_1d8ZUrez7mPBsvS8

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

@greptile-apps

greptile-apps Bot commented Feb 27, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes a critical bug where aw-watcher-afk would falsely exit when launched by modern init systems (launchd on macOS, systemd on Linux) that legitimately use PID 1 as the parent.

Key Changes:

  • Stores initial parent PID in __init__ for comparison instead of hardcoding PID 1 check
  • Changes detection logic from os.getppid() == 1 to os.getppid() != self._initial_ppid in heartbeat_loop()
  • Enhances log message to show old and new ppid values for easier debugging
  • Removes outdated PyInstaller TODO comment (now resolved by this approach)

The fix correctly handles both legitimate PID 1 parents and actual orphaned processes, while also solving the PyInstaller bootloader compatibility issue mentioned in the old TODO.

Confidence Score: 5/5

  • This PR is safe to merge with no identified issues
  • The fix is a simple, well-scoped change that correctly addresses the reported bug. The logic is sound: storing the initial ppid and detecting changes is the correct approach for orphan detection. No edge cases or safety issues identified.
  • No files require special attention

Important Files Changed

Filename Overview
aw_watcher_afk/afk.py Fixes parent death detection by checking ppid change instead of ppid==1; also removes PyInstaller TODO

Last reviewed commit: 7144da2

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, no comments

Edit Code Review Agent Settings | Greptile

@ErikBjare ErikBjare merged commit 94f88e3 into ActivityWatch:master Feb 27, 2026
1 of 3 checks 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.

Running aw-watcher-afk via launchd on macOS triggers "parent process died"

2 participants