Skip to content

No injection after a KernelSU emulated soft reboot spawns a duplicate daemon #878

Open

Description

@RMDycz

Steps to reproduce/复现步骤

Install the latest version of the Vector module on a Redmi K80 Pro (HyperOS + Zygisk Next + KSU jailbreak environment).

Soft reboot the device.

In the license manager, click the "Action" / "Open" button for the LSPosed module.

Observe that the interface redirects to a Shell warning or becomes unresponsive, and the test module cannot be hooked.

Expected behaviour/预期行为

Correct startup and hooking
The v2.1 version of vector (vector-v2.1-3076 HSSkyBoy version) runs normally.

Actual behaviour/实际行为

Unable to start vector and unable to perform hooking

Xposed Module List/Xposed 模块列表

Module unrelated

Root implementation/Root 方案

Root access was gained by disabling SELinux through a Qualcomm 8E series vulnerability, followed by KSU entering jailbreak mode.

System Module List/系统模块列表

Vector v2.2 3080-88f8e1fa
Zygisk-next-780-9d7024c-release

Vector version/Vector 版本

Vector v2.2 3080-88f8e1fa

Android version/Android 版本

16 - xiaomi HyperOS 3

Version requirement/版本要求

Logs/日志

locat-log.txt

Activity

  1. JingMatrix commented on Aug 6, 2026

    @JingMatrix
    Owner

    Please upload the log folder as indicated in #123.

  2. changed the title [-]The latest version (v2.2-3080-88f8e1fa) cannot be injected in the HyperOS (Redmi K80 Pro) + Zygisk Next environment; both the parasite manager and Hook functions are disabled (v2.1 works normally).[/-] [+] No injection under exploit-gained KernelSU jailbreak root[/+] on Aug 6, 2026
  3. RMDycz commented on Aug 6, 2026

    @RMDycz
    Author

    The current situation is a bit abnormal.

    I tried reinstalling the latest version of Vector and performing a soft reboot four times to reproduce the original problem. Each of these four tests yielded different results. The first two times, Vector crashed and failed to inject into the system framework. The third time, the DEX optimizer wrapper failed to mount. The fourth time, the problem reappeared after the reboot; Vector could not be opened. The logs should contain most of the logs from my tests from this morning to this afternoon.

    verbose-log1.txt

    @JingMatrix

  4. JingMatrix commented on Aug 6, 2026

    @JingMatrix
    Owner

    Let us enable only (Neo)Zygisk and Vector, do a full reboot, trigger Vector Action button, and then upload the whole folder /data/adb/lspd/log as logs (you have pack it in .zip by your own.)

  5. RMDycz commented on Aug 6, 2026

    @RMDycz
    Author

    Let us enable only (Neo)Zygisk and Vector, do a full reboot, trigger Vector Action button, and then upload the whole folder /data/adb/lspd/log as logs (you have pack it in .zip by your own.)

    I understand, but I can only perform the following steps:

    1. Uninstall the existing Vector

    2. Perform a hardware reboot

    3. Re-execute the vulnerability to jailbreak

    4. Install Vector

    5. Perform a soft reboot to make Vector effective

    If I don't do this, a hardware reboot will cause the KSU jailbreak to disappear.
    Can this solution find the problem?

  6. JingMatrix commented on Aug 6, 2026

    @JingMatrix
    Owner

    Yes, please do as you suggest. And remember to pack the logs for uploading.

  7. RMDycz commented on Aug 6, 2026

    @RMDycz
    Author

    Yes, please do as you suggest. And remember to pack the logs for uploading.

    I have followed the procedure. The current situation is:

    After a hardware reboot, reinstalling Vector and Vector runs normally.

    However, a subsequent soft reboot causes the aforementioned problem.

    The logs are attached; they should contain details of my two reboot attempts. The first reboot was normal, but the subsequent soft reboot caused the problem.

    vector_logs.zip

  8. changed the title [-] No injection under exploit-gained KernelSU jailbreak root[/-] [+]No injection after a KernelSU emulated soft reboot spawns a duplicate daemon[/+] on Aug 6, 2026
  9. JingMatrix commented on Aug 6, 2026

    @JingMatrix
    Owner

    Thanks, these logs are exactly what was needed. Root cause is clear now.

    The trigger is KernelSU's emulated soft reboot. It doesn't reboot the kernel — it runs stop, replays post-fs-data and services, then start. That tears down and respawns zygote (which is why NeoZygisk re-injects correctly), but it also re-runs every module's service.sh, including Vector's. The existing Vector daemon is a detached process, so stop doesn't kill it, and it has no idea a second service.sh was just fired. The result is two daemons: the survivor from the previous boot and a fresh one. Both claim the same rendezvous service, forward transactions to each other, and one crashes on a stack overflow. No framework gets injected, so the manager opens into the shell warning.

    This also matches what you saw: the first soft reboot after installing works because there's no prior daemon; every soft reboot after that collides with the one already running.

  10. JingMatrix commented on Aug 6, 2026

    @JingMatrix
    Owner

    It is hard to find a solution, you will have to wait.

    Currently, the only workaround for you, is to avoid soft-reboot from KernelSU

  11. RMDycz commented on Aug 7, 2026

    @RMDycz
    Author

    It is hard to find a solution, you will have to wait.

    Currently, the only workaround for you, is to avoid soft-reboot from KernelSU

    Why did some previous versions seem to have no problem? But overall, the issue isn't serious. Now that we know the cause, we can use the following temporary solution: disable vector in ksu, then perform a soft reboot, and then enable vector again and perform another soft reboot. This only requires an extra soft reboot.

  12. JingMatrix commented on Aug 7, 2026

    @JingMatrix
    Owner

    @RMDycz If you have some working version, please share the link and the logs generated by that build, it will help us to solve this in new versions of Vector.

  13. RMDycz commented on Aug 7, 2026

    @RMDycz
    Author

    @RMDycz If you have some working version, please share the link and the logs generated by that build, it will help us to solve this in new versions of Vector.

    Okay, the Vector v2.1 (3076-1e595f3c-HSSkyBoy) version I mentioned before also has the same problem. However, I can confirm that Vector 2.0 Mar 23 version does not have this issue because I have been using this version for a considerable period of time.

  14. RMDycz commented on Aug 10, 2026

    @RMDycz
    Author

    @RMDycz If you have some working version, please share the link and the logs generated by that build, it will help us to solve this in new versions of Vector.

    This could also be an issue with the KSU update, because the KSU version I was using before was an older one, probably the May version of Vector and the May version of KSU. It might take some time to test the versions to find out exactly where the problem lies.

  15. 1 remaining item

  16. astr64 commented on Aug 13, 2026

    @astr64

    I can confirm @H3XDaemon 's solution does not work on Pixel devices running rootmypixel.

    I still experience identical issues.

  17. H3XDaemon commented on Aug 13, 2026

    @H3XDaemon

    @astr64 Thanks — worth separating, because two failures in this thread look identical from the UI and the kill only covers one.

    One thing ruled out first: the ksud that Root-My-Pixel ships (app/src/main/assets/ksud/ksud-android15-6.6, sha256 cdc8f210…) contains the emulated-soft-reboot stage, and ReSukiSU's soft_reboot() and run_stage() are line-for-line the same as upstream's, including the on_services() call that re-runs service.sh. So on your setup the stage exists and so does the bug — the difference is not the version.

    Duplicate daemon, script absent, fresh boot, three consecutive soft reboots:

    cycle vectord pid injected failed to inject
    1 10020 yes —
    2 10020 yes yes
    3 10020 no yes

    The pid is frozen across all three; cycle 1 is clean only because there is no survivor yet. With the script, seven cycles across two boots: one daemon each, injected each, pid changing every cycle instead of freezing.

    A false negative worth ruling out: my first check logged the marker to /dev/kmsg and read back nothing, because the soft reboot's own message burst rotates the ring buffer within seconds. I nearly concluded the stage never runs. A file showed it running normally.

    Three things that separate the cases:

    1. echo "$(date) [$(pgrep -f '^vectord')]" >> /data/local/tmp/esr-trace.log as the script's first line, soft reboot, then cat it. Empty = the stage never ran and the kill is still untested.
    2. pgrep -f '^vectord' while Vector is healthy. Empty = the pattern does not match on your build, so the script is a no-op even when it runs.
    3. If the trace is empty, check the ksud log for Magisk detected, skip or safe mode, skip — run_stage returns early on either and only logs a warning.

    If the trace shows the kill happening and injection still fails with a single daemon and no StackOverflowError, that is a different failure from this one and worth its own logs — the daemon comes up before system_server on every cycle and the wait loop normally handles it, so the interesting question there is what the servicemanager lookup returned.

    Limits: seven cycles with the script, four without, across three boots on one device and one SoC. No Pixel data.

  18. astr64 commented on Aug 13, 2026

    @astr64

    @astr64 Thanks — worth separating, because two failures in this thread look identical from the UI and the kill only covers one.

    One thing ruled out first: the ksud that Root-My-Pixel ships (app/src/main/assets/ksud/ksud-android15-6.6, sha256 cdc8f210…) contains the emulated-soft-reboot stage, and ReSukiSU's soft_reboot() and run_stage() are line-for-line the same as upstream's, including the on_services() call that re-runs service.sh. So on your setup the stage exists and so does the bug — the difference is not the version.

    Hallucinated AI Babble goes on

    I don't understand the point of a blind troubleshooting AI frenzy. It ultimately does nothing right. We all have access to LLMs and can burn tokens until we get to a working product.

  19. JingMatrix commented on Aug 13, 2026

    @JingMatrix
    Owner

    @astr64 I will review the PR once it iterates till a mature stage.

    No worries, quality of merged code is always guaranteed.

  20. astr64 commented on Aug 13, 2026

    @astr64

    @JingMatrix What sort of logs can I provide to benefit development and fixing this bug?

    I enter a double soft loop with basically any version of Vector (tried 2.0, 2.1, 2.2, and the latest 2.2 betas)

  21. JingMatrix commented on Aug 13, 2026

    @JingMatrix
    Owner

    @astr64 I have not an implementation plan yet, let us be patient. I am currently busy with TEESimulator.

    The support is broken now for sure. I will ask for your test once I start to inspect a solution. Thanks

  22. astr64 commented on Aug 13, 2026

    @astr64

    TEESimulator

    Thank you for your service and work on TEE, and hit me up when you tackle this issue! Godspeed

  23. ManiaciaChao commented on Aug 24, 2026

    @ManiaciaChao

    Based on our discussion, I made a KSU module as a temporary workaround until PR #914 is merged, for those who want to use Vector with a late-loaded KSU. It uses the emulated-soft-reboot hook to kill the previous vectord process whenever a soft reboot is performed.

    vector-soft-reboot-guard-v0.1.0.zip

    It still has a problem:

    After a soft reboot, the global dex2oat bind mount remains in place. The new vectord then treats the already-wrapped path as the stock dex2oat, so once dexopt is triggered, the wrapper ends up recursively execing itself.

  24. astr64 commented on Aug 24, 2026

    @astr64

    Based on our discussion, I made a KSU module as a temporary workaround until PR #914 is merged, for those who want to use Vector with a late-loaded KSU. It uses the emulated-soft-reboot hook to kill the previous vectord process whenever a soft reboot is performed.

    vector-soft-reboot-guard-v0.1.0.zip

    I rebuilt vector with 914 applied, and it didn't work for me. Any info can provide? (Pixel 10, Root My Pixel)

  25. ManiaciaChao commented on Aug 24, 2026

    @ManiaciaChao

    Based on our discussion, I made a KSU module as a temporary workaround until PR #914 is merged, for those who want to use Vector with a late-loaded KSU. It uses the emulated-soft-reboot hook to kill the previous vectord process whenever a soft reboot is performed.
    vector-soft-reboot-guard-v0.1.0.zip

    I rebuilt vector with 914 applied, and it didn't work for me. Any info can provide? (Pixel 10, Root My Pixel)

    I think the implementation in #914 is still not quite correct. As I mentioned above, stale dex2oat bind mounts can still remain after a soft reboot.

    I've added some additional cleanup logic to the KSU module. You can use an official Vector build without #914 together with this updated module to verify whether the issue is fixed.

    vector-soft-reboot-guard-v0.2.0.zip

    Note: The first soft reboot after installing this module only activates it. You'll need to perform one more soft reboot to clean up the stale state and verify whether vectord restarts normally.

  26. ezariago commented on Sep 9, 2026

    @ezariago

    I think the implementation in #914 is still not quite correct. As I mentioned above, stale dex2oat bind mounts can still remain after a soft reboot.

    I've added some additional cleanup logic to the KSU module. You can use an official Vector build without #914 together with this updated module to verify whether the issue is fixed.

    vector-soft-reboot-guard-v0.2.0.zip

    Note: The first soft reboot after installing this module only activates it. You'll need to perform one more soft reboot to clean up the stale state and verify whether vectord restarts normally.

    Hi! I used the soft reboot guard you've attached, but sadly it doesn't really do anything

  27. grischuk-c commented on Sep 21, 2026

    @grischuk-c

    @H3XDaemon your solution works fine on samsung, i had to include small change., after soft reboot trying to install any app causes system crash.

    1789994679.653 artd 980 980 W LSPlt : symbol _ZNK3art9OatHeader16GetKeyValueStoreEv not found in PLT table
    1789994679.643 artd 980 980 W LSPlt : symbol _ZNK3art9OatHeader16GetKeyValueStoreEv not found in PLT table
    1789994679.634 artd 980 980 W LSPlt : symbol _ZNK3art9OatHeader16GetKeyValueStoreEv not found in PLT table

    setenforce 0 , makes vectord to umount dex2oat [https://github.com/JingMatrix/Vector/blob/master/daemon/src/main/kotlin/org/matrix/vector/daemon/env/Dex2OatServer.kt#L86] , fixing the crash

    emulated-soft-reboot.sh

    pids=$(pgrep -f '^vectord')
    if [ -n "$pids" ]; then
    setenforce 0
    sleep 1
    kill -9 $pids
    setenforce 1
    fi

    exit 0

    Edit:- i think we can directly call umount

  28. bartasc4 commented on Oct 17, 2026

    @bartasc4

    I opened #1012, building on H3XDaemon's pre-stop hook and ManiaciaChao's stale compiler-mount diagnosis. It handles both the surviving daemon and its mounts, including first-update post-fs-data cleanup, without relying on the process name or toggling SELinux.

    It includes the complete script-level lifecycle change, applies directly to master, and does not depend on #914 or #1008. It overlaps #914; the separate compiler recursion guards from #1008 are not included.

    It includes 24 Linux integration tests (passing with dash, BusyBox and mksh). The same four production scripts were observed through one successful Android 12 cycle; validation details and limits are in the PR.

  29. kinghe2023 commented on Oct 18, 2026

    @kinghe2023

    Confirming this on a second device, plus one KernelSU behaviour worth knowing while testing the hooks above.

    Device: Samsung Galaxy S25 (SM-S931U1), Android 16 / One UI 8, KernelSU v3.2.5 LKM late-load (locked bootloader), Vector v2.2 (3080), Zygisk Next 1.5.2.

    The stage does run here — our emulated-soft-reboot.sh writes a line to a file, and the timestamps line up with a real ksud soft-reboot. (/dev/kmsg is useless for this: the soft reboot's own burst rotates the ring buffer within seconds.)

    Three things I did not see above:

    1. KernelSU applies module mounts once per load, not per soft reboot. A module installed while late-loaded is not mounted by a later ksud soft-reboot: the scripts are replayed, the overlay is not re-created. We watched this with a module of ours that ships a permission XML and an overlay library — after ksud post-fs-data (and after a soft reboot) the files were still absent from /system, /proc/1/mountinfo had no matching entry, and that module's own post-fs-data.sh had clearly run. So the "the first soft reboot after installing only activates it" note above is not a quirk of that particular module — it is how the mount stage behaves. Anything that has to be live sooner must be brought in by hand (mount --bind), which is how we ended up testing it.

    2. On this firmware ksud soft-reboot is not a safe way to get Vector back up, even with the duplicate handled. Our last attempt had system_server come up before the APEX-provided android.ext.services package was resolvable (Required services extension package is missing ... android.ext.services), crash-loop, and Rescue Party reboot the device — losing root, since a late-loaded LKM does not survive a real reboot. What we do instead: start vectord first (it claims the serial proxy name early), then start Zygisk Next and let its zygote restart hand the new system_server to the waiting daemon. That is KernelSU-side rather than Vector-side, but it is why "just avoid the soft reboot" is a cheap workaround on a normal device and an expensive one here.

    3. A three-line guard for the case where the KernelSU stage does not exist (Magisk, APatch) or does not run. Starting a second daemon is what creates the collision, and service.sh can notice that one is already alive: if pgrep -f '^vectord' >/dev/null 2>&1; then exit 0; fi. Anchored, because app_process sets the nice name in argv only — comm stays main, so pkill vectord matches nothing, while an unanchored pattern matches any shell whose command line happens to contain the word.

    What a daemon restart leaves behind when system_server is already running — a permanently false "not injected" state with no repair path — is filed separately: #1015.

  30. bartasc4 commented on Oct 18, 2026

    @bartasc4

    I opened #1017 for the daemon-restart gap described here and in #1015. It re-registers an already injected system_server through the existing bridge, restores loaded modern modules’ IPC/preferences and hot-reload targets, and derives manager status from the live registration. It does not rerun module entry points or reinstall hooks. Native startup also waits for a successful registration handshake rather than accepting an unrelated binder at the proxy name.

    This complements #1012’s daemon/compiler-mount cleanup and applies directly to master. #1018 separately releases consumed hot-reload resources and retired callbacks. The three changes also compile and pass their regression suites together.

    An Android 12/NeoZygisk local validation build passed daemon replacements with unchanged system_server/zygote PID and start times, then a KernelSU emulated soft reboot followed by application and hot-reload tests. Clean PR sources were compiled separately. I have not reproduced the locked-bootloader LKM setup; these changes do not restore external overlays or fix the reported APEX/extension-package failure.

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

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions