{"record":{"id":"65528877153b7df9","repo":"shadowsocks/shadowsocks-rust","slug":"signal","errorCode":null,"errorMessage":"signal","messagePattern":"signal","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/service/local.rs","lineNumber":1122,"sourceCode":"        let total_end_time = Instant::now();\n\n        info!(\n            \"server-loader task load from {} with {} servers, fetch costs: {:?}, total costs: {:?}\",\n            self.config_path.display(),\n            server_len,\n            fetch_end_time - start_time,\n            total_end_time - start_time,\n        );\n\n        Ok(())\n    }\n\n    #[cfg(unix)]\n    async fn launch_signal_reload_server_task(self: Arc<Self>) {\n        use log::debug;\n        use tokio::signal::unix::{SignalKind, signal};\n\n        let mut sigusr1 = signal(SignalKind::user_defined1()).expect(\"signal\");\n\n        debug!(\"server-loader task is now listening USR1\");\n\n        while sigusr1.recv().await.is_some() {\n            let _ = self.run_once().await;\n        }\n    }\n\n    #[cfg(unix)]\n    async fn launch_reload_server_task(self) {\n        let arc_self = Arc::new(self);\n        arc_self.launch_signal_reload_server_task().await\n    }\n\n    #[cfg(windows)]\n    async fn launch_reload_server_task(self) {\n        let _ = self.config_path;\n        let _ = self.balancer;","sourceCodeStart":1104,"sourceCodeEnd":1140,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/src/service/local.rs#L1104-L1140","documentation":"`launch_signal_reload_server_task` registers a SIGUSR1 handler via `tokio::signal::unix::signal(SignalKind::user_defined1()).expect(\"signal\")`. The expect panics when the OS refuses to install the signal handler, e.g. signal limits (RLIMIT_SIGPENDING) exhausted or an unsupported/invalid signal kind on the platform. This only runs on Unix (`#[cfg(unix)]`).","triggerScenarios":"Calling `signal(SignalKind::user_defined1())` when the kernel/OS rejects handler registration — resource limits reached, or running in an environment that blocks signal handler installation (some sandboxes/seccomp profiles).","commonSituations":"Heavily loaded containers that exhausted the per-user pending-signal limit; seccomp filters blocking rt_sigaction; non-Unix platforms (excluded by cfg, so practically Unix sandboxes only).","solutions":["Check and raise RLIMIT_SIGPENDING / process signal limits","Review sandbox/seccomp policies allowing rt_sigaction for SIGUSR1","Make signal registration non-fatal (log a warning and skip hot-reload support)","Restart the host/container if signal limits are leaked"],"exampleFix":"// before\nlet mut sigusr1 = signal(SignalKind::user_defined1()).expect(\"signal\");\n// after\nlet sigusr1 = match signal(SignalKind::user_defined1()) {\n    Ok(s) => s,\n    Err(err) => { log::warn!(\"SIGUSR1 reload disabled: {err}\"); return; }\n};","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"// avoid .expect on signal registration; degrade gracefully\nlet mut sigusr1 = match tokio::signal::unix::signal(SignalKind::user_defined1()) {\n    Ok(s) => s,\n    Err(e) => { log::warn!(\"hot-reload disabled: {e}\"); return; }\n};","preventionTips":["Monitor RLIMIT_SIGPENDING on busy hosts","Whitelist rt_sigaction in seccomp profiles","Treat hot-reload as optional, never crash on its absence"],"tags":["unix","signal","tokio","panic"],"backgroundTag":"permission-denied","analyzedSha":"8eb0f0a65b1d976ab6bed5787327ef86529b0435","analyzedAt":"2026-09-09T12:20:43.168Z","contentChangedAt":"2026-09-09T12:20:43.168Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}