shadowsocks/shadowsocks-rust · error
signal
Error message
signal
What it means
`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)]`).
Source
Thrown at src/service/local.rs:1122
let total_end_time = Instant::now();
info!(
"server-loader task load from {} with {} servers, fetch costs: {:?}, total costs: {:?}",
self.config_path.display(),
server_len,
fetch_end_time - start_time,
total_end_time - start_time,
);
Ok(())
}
#[cfg(unix)]
async fn launch_signal_reload_server_task(self: Arc<Self>) {
use log::debug;
use tokio::signal::unix::{SignalKind, signal};
let mut sigusr1 = signal(SignalKind::user_defined1()).expect("signal");
debug!("server-loader task is now listening USR1");
while sigusr1.recv().await.is_some() {
let _ = self.run_once().await;
}
}
#[cfg(unix)]
async fn launch_reload_server_task(self) {
let arc_self = Arc::new(self);
arc_self.launch_signal_reload_server_task().await
}
#[cfg(windows)]
async fn launch_reload_server_task(self) {
let _ = self.config_path;
let _ = self.balancer;View on GitHub (pinned to 8eb0f0a65b)
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
Example fix
// before
let mut sigusr1 = signal(SignalKind::user_defined1()).expect("signal");
// after
let sigusr1 = match signal(SignalKind::user_defined1()) {
Ok(s) => s,
Err(err) => { log::warn!("SIGUSR1 reload disabled: {err}"); return; }
}; Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
// avoid .expect on signal registration; degrade gracefully
let mut sigusr1 = match tokio::signal::unix::signal(SignalKind::user_defined1()) {
Ok(s) => s,
Err(e) => { log::warn!("hot-reload disabled: {e}"); return; }
}; Prevention
- Monitor RLIMIT_SIGPENDING on busy hosts
- Whitelist rt_sigaction in seccomp profiles
- Treat hot-reload as optional, never crash on its absence
When it happens
Trigger: 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).
Common situations: 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).
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- cannot get current working directory, {err:?}
- cannot get absolute path to working directory, {err:?}
- errno
- create tokio Runtime
- create tokio Runtime
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/65528877153b7df9.
Report an issue: GitHub.