{"record":{"id":"511ec701c559e6bb","repo":"Tencent/matrix","slug":"backgroundlrukill-should-only-be-called-in-supervi","errorCode":null,"errorMessage":"backgroundLruKill should only be called in supervisor","messagePattern":"backgroundLruKill should only be called in supervisor","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/lifecycle/supervisor/SupervisorService.kt","lineNumber":285,"sourceCode":"        MatrixLog.d(TAG, \"onBind\")\n        return binder\n    }\n\n    override fun onDestroy() {\n        super.onDestroy()\n        MatrixLog.e(TAG, \"SupervisorService destroyed!!!\")\n        instance = null\n    }\n\n    internal fun backgroundLruKill(\n        killedCallback: (result: Int, process: String?, pid: Int) -> Unit\n    ) {\n        if (true != ProcessSupervisor.config?.enable) {\n            MatrixLog.e(TAG, \"supervisor was disabled\")\n            return\n        }\n        if (!isSupervisor) {\n            throw IllegalStateException(\"backgroundLruKill should only be called in supervisor\")\n        }\n\n        if (instance == null) {\n            throw IllegalStateException(\"not initialized yet !\")\n        }\n\n        targetKilledCallback = killedCallback\n        val candidate = backgroundProcessLru.firstOrNull {\n            it.name != MatrixUtil.getProcessName(this)\n                    && !ProcessSupervisor.config!!.lruKillerWhiteList.contains(it.name)\n        }\n\n        if (candidate != null) {\n//            DispatchReceiver.dispatchKill(this, candidate.name, candidate.pid)\n            ProcessSubordinate.manager.dispatchKill(recentScene, candidate.name, candidate.pid)\n        } else {\n            killedCallback.invoke(LRU_KILL_NOT_FOUND, null, -1)\n        }","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/lifecycle/supervisor/SupervisorService.kt#L267-L303","documentation":"SupervisorService.backgroundLruKill() performs LRU-based killing of background processes and is restricted to the supervisor process. It throws IllegalStateException when called while ProcessSupervisor.isSupervisor is false, preventing non-supervisor processes from triggering process kills.","triggerScenarios":"Calling backgroundLruKill(...) from a subordinate process, or before ProcessSupervisor.init has determined the role (which also surfaces init errors); any call path where the supervisor role check fails.","commonSituations":"Memory-pressure callbacks that run in every process but invoke backgroundLruKill unconditionally; testing on a device where the supervisor service was not the calling process; disabled supervisor config causing role detection to differ from expectation.","solutions":["Guard the call with `if (ProcessSupervisor.isSupervisor)` before invoking backgroundLruKill.","Move LRU-kill invocations into supervisor-only code (e.g. inside the SupervisorService).","Verify ProcessSupervisor.init ran and enable flags make this process the supervisor.","Skip the operation gracefully (log and return) in non-supervisor processes instead of calling."],"exampleFix":"// before\nSupervisorService.backgroundLruKill(killedCallback)\n// after\nif (ProcessSupervisor.isSupervisor) {\n    SupervisorService.backgroundLruKill(killedCallback)\n}","handlingStrategy":"validation","validationCode":"if (ProcessSupervisor.isSupervisor) {\n    SupervisorService.backgroundLruKill(killedCallback)\n} else {\n    MatrixLog.w(TAG, \"backgroundLruKill skipped: not supervisor\")\n}","typeGuard":"fun canBackgroundLruKill(): Boolean =\n    runCatching { ProcessSupervisor.isSupervisor }.getOrDefault(false)","tryCatchPattern":"try {\n    SupervisorService.backgroundLruKill(killedCallback)\n} catch (e: IllegalStateException) {\n    MatrixLog.w(TAG, \"lru kill forbidden outside supervisor\", e)\n}","preventionTips":["Only invoke LRU kill from the supervisor process.","Route memory-pressure decisions to a single supervisor-side component.","Confirm the supervisor role at startup and log mismatches early."],"tags":["android","process-supervisor","lru-kill","api-misuse"],"backgroundTag":"insufficient-permissions","analyzedSha":"3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7","analyzedAt":"2026-09-08T08:01:39.722Z","contentChangedAt":"2026-09-08T08:01:39.722Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}