Fix segfault from Alpine version mismatch, add crash handler
The builder (rust:1.93-alpine) uses Alpine 3.23 but the runtime used Alpine 3.19. The net-snmp-dev headers from 3.23 don't match net-snmp-libs from 3.19, causing a segfault on the first SNMP call. Also adds a SIGSEGV/SIGBUS/SIGABRT signal handler that prints a diagnostic message instead of silently exiting with code 139.
This commit is contained in:
parent
fa46d279a7
commit
29b94c09d4
2 changed files with 36 additions and 2 deletions
|
|
@ -52,8 +52,9 @@ RUN --mount=type=cache,id=cargo-registry-${TARGETARCH},target=/usr/local/cargo/r
|
||||||
BUILD_VERSION="$VERSION" cargo build --release --target "$RUST_TARGET" && \
|
BUILD_VERSION="$VERSION" cargo build --release --target "$RUST_TARGET" && \
|
||||||
cp "target/$RUST_TARGET/release/towerops-agent" /tmp/towerops-agent
|
cp "target/$RUST_TARGET/release/towerops-agent" /tmp/towerops-agent
|
||||||
|
|
||||||
# Runtime stage
|
# Runtime stage - must match builder's Alpine version for ABI compatibility
|
||||||
FROM alpine:3.19
|
# (rust:1.93-alpine uses Alpine 3.23)
|
||||||
|
FROM alpine:3.23
|
||||||
|
|
||||||
# Install runtime dependencies
|
# Install runtime dependencies
|
||||||
# iputils provides ping with setuid root (doesn't require CAP_NET_RAW)
|
# iputils provides ping with setuid root (doesn't require CAP_NET_RAW)
|
||||||
|
|
|
||||||
33
src/main.rs
33
src/main.rs
|
|
@ -116,7 +116,40 @@ struct Args {
|
||||||
snmpv3_priv_pass: String,
|
snmpv3_priv_pass: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn install_crash_handler() {
|
||||||
|
unsafe {
|
||||||
|
// Install a signal handler for SIGSEGV/SIGBUS/SIGABRT so we get
|
||||||
|
// diagnostic output instead of a silent exit code 139.
|
||||||
|
extern "C" fn crash_handler(sig: libc::c_int) {
|
||||||
|
let name = match sig {
|
||||||
|
libc::SIGSEGV => "SIGSEGV (segmentation fault)",
|
||||||
|
libc::SIGBUS => "SIGBUS (bus error)",
|
||||||
|
libc::SIGABRT => "SIGABRT (abort)",
|
||||||
|
_ => "unknown signal",
|
||||||
|
};
|
||||||
|
let msg = format!(
|
||||||
|
"\n*** FATAL: {} (signal {})\n\
|
||||||
|
*** This is likely a bug in C FFI code (libnetsnmp).\n\
|
||||||
|
*** Set RUST_BACKTRACE=1 for more info.\n",
|
||||||
|
name, sig
|
||||||
|
);
|
||||||
|
unsafe {
|
||||||
|
libc::write(libc::STDERR_FILENO, msg.as_ptr() as _, msg.len());
|
||||||
|
// Re-raise with default handler to get the correct exit code
|
||||||
|
libc::signal(sig, libc::SIG_DFL);
|
||||||
|
libc::raise(sig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
libc::signal(libc::SIGSEGV, crash_handler as libc::sighandler_t);
|
||||||
|
libc::signal(libc::SIGBUS, crash_handler as libc::sighandler_t);
|
||||||
|
libc::signal(libc::SIGABRT, crash_handler as libc::sighandler_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
install_crash_handler();
|
||||||
|
|
||||||
// Install ring as the default TLS crypto provider. Required because both
|
// Install ring as the default TLS crypto provider. Required because both
|
||||||
// ring and aws-lc-rs features are enabled transitively, so rustls can't
|
// ring and aws-lc-rs features are enabled transitively, so rustls can't
|
||||||
// auto-detect which one to use.
|
// auto-detect which one to use.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue