From 842ab62b05137920c4d3e076f61cf65c3877f0ec Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Mon, 9 Feb 2015 23:13:50 +0000 Subject: [PATCH] Notify devd(8) when a process crashed. This change implements a notification (via devctl) to userland when the kernel produces coredumps after a process has crashed. devd can then run a specific command to produce a human readable crash report. The command is most usually a helper that runs gdb/lldb commands on the file/coredump pair. It's possible to use this functionality for implementing automatic generation of crash reports. devd(8) will be notified of the full path of the binary that crashed and the full path of the coredump file. --- etc/devd.conf | 12 ++++++++++++ sys/kern/kern_sig.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/etc/devd.conf b/etc/devd.conf index 4120c637c19f..7a033a71dc48 100644 --- a/etc/devd.conf +++ b/etc/devd.conf @@ -325,4 +325,16 @@ notify 100 { action "/usr/sbin/automount -c"; }; +# Handle userland coredumps. +# This commented out handler makes it possible to run an +# automated debugging session after the core dump is generated. +# Replace action with a proper coredump handler, but be aware that +# it will run with elevated privileges. +notify 10 { + match "system" "kernel"; + match "subsystem" "signal"; + match "type" "coredump"; + action "logger $comm $core"; +}; + */ diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 45cb4b95630c..f25fc16fa6f3 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -3237,6 +3238,9 @@ coredump(struct thread *td) void *rl_cookie; off_t limit; int compress; + char *data = NULL; + size_t len; + char *fullpath, *freepath = NULL; #ifdef COMPRESS_USER_CORES compress = compress_user_cores; @@ -3322,9 +3326,36 @@ coredump(struct thread *td) error1 = vn_close(vp, FWRITE, cred, td); if (error == 0) error = error1; + else + goto out; + /* + * Notify the userland helper that a process triggered a core dump. + * This allows the helper to run an automated debugging session. + */ + len = MAXPATHLEN * 2 + 5 /* comm= */ + 5 /* core= */ + 1; + data = malloc(len, M_TEMP, M_NOWAIT); + if (data == NULL) + goto out; + if (vn_fullpath_global(td, p->p_textvp, &fullpath, &freepath) != 0) + goto out; + snprintf(data, len, "comm=%s", fullpath); + if (freepath != NULL) { + free(freepath, M_TEMP); + freepath = NULL; + } + if (vn_fullpath_global(td, vp, &fullpath, &freepath) != 0) + goto out; + snprintf(data, len, "%s core=%s", data, fullpath); + devctl_notify("kernel", "signal", "coredump", data); + free(name, M_TEMP); +out: #ifdef AUDIT audit_proc_coredump(td, name, error); #endif + if (freepath != NULL) + free(freepath, M_TEMP); + if (data != NULL) + free(data, M_TEMP); free(name, M_TEMP); return (error); }