Skip to content

Keep the daemon's lock where the shrinker cannot reach it - #1049

Merged
JingMatrix merged 1 commit into
masterfrom
daemon-lock-outlives-shrinking
Oct 30, 2026
Merged

JingMatrix merged 1 commit into
masterfrom
daemon-lock-outlives-shrinking

Conversation

@JingMatrix

Copy link
Copy Markdown
Owner

/data/adb/lspd/lock is how a second daemon is turned away, and in a release build it stops holding a fifth of a second into every boot. tryLock kept the channel and the lock in two private fields nothing read again, and a shrinker deletes such a field. The channel is collected, its finalizer closes the descriptor, and closing any descriptor drops every POSIX lock on that file. #996's log shows it: a CloseGuard warning for FileChannel.open inside main, 196 ms after the start line. Debug builds keep the fields and work, and the template asks for debug logs, so local tests never showed it. H3XDaemon diagnosed it first.

With it open, every KernelSU soft reboot replays service.sh and leaves two daemons claiming serial. servicemanager hands each the other's binder, adoptOriginService cannot tell a sibling from the real service, and the pair forwards one transaction back and forth. 14 ms later one daemon is in a tombstone and the survivor is forwarding to a corpse.

The reference now lives in a shutdown hook, which the platform holds and which reads both halves; an orderly exit returns the lock. #914 handles the same reboot by killing the old daemon from the shell; with the lock holding, the new one stands down instead and the old one re-injects.

Left alone: the adoption loop itself, and the stripped Log.d calls that keep this out of a release log. No device result of mine yet; this rests on the release-against-debug rounds in #878.

/data/adb/lspd/lock is how a second daemon is turned away, and in a release
build it stops holding a fifth of a second into every boot. tryLock kept the
channel and the lock in two private fields nothing read again, and a shrinker
deletes such a field: the channel is collected, its finalizer closes the
descriptor, and closing any descriptor drops every POSIX lock on the file.
Debug builds keep the fields and work, so local tests never showed it.

Every KernelSU soft reboot replays service.sh, so two daemons claim `serial`,
servicemanager hands each the other's binder, and onTransact forwards one
transaction back and forth until a binder thread's stack gives out. The
survivor keeps the name and forwards to a corpse until a real reboot.

The reference now lives in a shutdown hook, which the platform holds and
which reads both halves; an orderly exit returns the lock.

Fixes #878
@cicoperfetto32-ux

Copy link
Copy Markdown

Wanted to add that trying the build in https://github.com/JingMatrix/Vector/actions/runs/41110752571 and doing a KernelSU soft restart a few times, the bug was finally fixed and Vector was activated. This was very bad initially since I think also caused some problems that I could only fix deleting lspd folder from /data/adb/modules/lspd but now that is fixed I can use it. I will tell you if any other problem occuring with soft restart, as for now I did 3-4 soft restarts and worked .
Thank you ❤️❤️🎉

@JingMatrix
JingMatrix merged commit 5690481 into master Oct 30, 2026
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