Skip to content

Commit 988e89e

Browse files
committed
coredump: implement logging of external backtraces with --backtrace
This is useful for example for Python progams. By installing a python sys.execepthook we can store the backtrace in the journal. We gather the backtrace in the python process, and call systemd-coredump to attach additional fields (COREDUMP_COMM, COREDUMP_EXE, COREDUMP_UNIT, COREDUMP_USER_UNIT, COREDUMP_OWNER_UID, COREDUMP_SLICE, COREDUMP_CMDLINE, COREDUMP_CGROUP, COREDUMP_OPEN_FDS, COREDUMP_PROC_STATUS, COREDUMP_PROC_MAPS, COREDUMP_PROC_LIMITS, COREDUMP_PROC_MOUNTINFO, COREDUMP_CWD, COREDUMP_ROOT, COREDUMP_ENVIRON, COREDUMP_CONTAINER_CMDLINE). This could also be done in the python process, but doing this in systemd-coredump saves quite a bit of duplicate work and unifies the handling of various tricky fields like COREDUMP_CONTAINER_CMDLINE in one place. (Of course this applies to any other language which does not dump cores but wants to log a traceback, e.g. ruby.) journal entry: _TRANSPORT=journal _UID=1002 _GID=1002 _CAP_EFFECTIVE=0 _AUDIT_LOGINUID=1002 _SYSTEMD_OWNER_UID=1002 _SYSTEMD_SLICE=user-1002.slice _SYSTEMD_USER_SLICE=-.slice _SELINUX_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 _BOOT_ID=1531fd22ec84429e85ae888b12fadb91 _MACHINE_ID=519a16632fbd4c71966ce9305b360c9c _HOSTNAME=laptop _AUDIT_SESSION=1 _SYSTEMD_UNIT=user@1002.service _SYSTEMD_INVOCATION_ID=3c4238d790a44aca9576ecdb2c7576d3 COREDUMP_UNIT=user@1002.service COREDUMP_USER_UNIT=gnome-terminal-server.service COREDUMP_UID=1002 COREDUMP_GID=1002 COREDUMP_OWNER_UID=1002 COREDUMP_SLICE=user-1002.slice COREDUMP_CGROUP=/user.slice/user-1002.slice/user@1002.service/gnome-terminal-server.service COREDUMP_PROC_LIMITS=Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 8388608 unlimited bytes Max core file size unlimited unlimited bytes Max resident set unlimited unlimited bytes Max processes 15413 15413 processes Max open files 4096 4096 files Max locked memory 65536 65536 bytes Max address space unlimited unlimited bytes Max file locks unlimited unlimited locks Max pending signals 15413 15413 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited us COREDUMP_PROC_CGROUP=1:name=systemd:/ 0::/user.slice/user-1002.slice/user@1002.service/gnome-terminal-server.service COREDUMP_PROC_MOUNTINFO=17 39 0:17 / /sys rw,nosuid,nodev,noexec,relatime shared:6 - sysfs sysfs rw,seclabel 18 39 0:4 / /proc rw,nosuid,nodev,noexec,relatime shared:5 - proc proc rw 19 39 0:6 / /dev rw,nosuid shared:2 - devtmpfs devtmpfs rw,seclabel,size=1972980k,nr_inodes=493245,mode=755 20 17 0:18 / /sys/kernel/security rw,nosuid,nodev,noexec,relatime shared:7 - securityfs securityfs rw 21 19 0:19 / /dev/shm rw,nosuid,nodev shared:3 - tmpfs tmpfs rw,seclabel 22 19 0:20 / /dev/pts rw,nosuid,noexec,relatime shared:4 - devpts devpts rw,seclabel,gid=5,mode=620,ptmxmode=000 23 39 0:21 / /run rw,nosuid,nodev shared:12 - tmpfs tmpfs rw,seclabel,mode=755 24 17 0:22 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:8 - cgroup2 cgroup rw 25 17 0:23 / /sys/fs/pstore rw,nosuid,nodev,noexec,relatime shared:9 - pstore pstore rw,seclabel 36 17 0:24 / /sys/kernel/config rw,relatime shared:10 - configfs configfs rw 39 0 0:26 /root / rw,relatime shared:1 - btrfs /dev/mapper/fedora-root2 rw,seclabel,ssd,space_cache,subvolid=257,subvol=/root 26 17 0:16 / /sys/fs/selinux rw,relatime shared:11 - selinuxfs selinuxfs rw 27 19 0:15 / /dev/mqueue rw,relatime shared:13 - mqueue mqueue rw,seclabel 28 18 0:30 / /proc/sys/fs/binfmt_misc rw,relatime shared:14 - autofs systemd-1 rw,fd=35,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=13663 29 17 0:7 / /sys/kernel/debug rw,relatime shared:15 - debugfs debugfs rw,seclabel 30 19 0:31 / /dev/hugepages rw,relatime shared:16 - hugetlbfs hugetlbfs rw,seclabel 31 18 0:32 / /proc/fs/nfsd rw,relatime shared:17 - nfsd nfsd rw 32 28 0:33 / /proc/sys/fs/binfmt_misc rw,relatime shared:18 - binfmt_misc binfmt_misc rw 57 39 0:34 / /tmp rw,relatime shared:19 - tmpfs none rw,seclabel 61 57 0:35 / /tmp/test rw,relatime shared:20 - autofs systemd-1 rw,fd=48,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=18251 59 39 8:1 / /boot rw,relatime shared:21 - ext4 /dev/sda1 rw,seclabel,data=ordered 60 39 253:2 / /home rw,relatime shared:22 - ext4 /dev/mapper/fedora-home rw,seclabel,data=ordered 65 39 0:37 / /var/lib/nfs/rpc_pipefs rw,relatime shared:23 - rpc_pipefs sunrpc rw 136 23 0:39 / /run/user/1002 rw,nosuid,nodev,relatime shared:91 - tmpfs tmpfs rw,seclabel,size=397432k,mode=700,uid=1002,gid=1002 211 23 0:41 / /run/user/42 rw,nosuid,nodev,relatime shared:163 - tmpfs tmpfs rw,seclabel,size=397432k,mode=700,uid=42,gid=42 329 136 0:44 / /run/user/1002/gvfs rw,nosuid,nodev,relatime shared:277 - fuse.gvfsd-fuse gvfsd-fuse rw,user_id=1002,group_id=1002 287 61 253:3 / /tmp/test rw,relatime shared:236 - ext4 /dev/mapper/fedora-test rw,seclabel,data=ordered 217 23 0:42 / /run/user/1000 rw,nosuid,nodev,relatime shared:168 - tmpfs tmpfs rw,seclabel,size=397432k,mode=700,uid=1000,gid=1000 225 217 0:43 / /run/user/1000/gvfs rw,nosuid,nodev,relatime shared:175 - fuse.gvfsd-fuse gvfsd-fuse rw,user_id=1000,group_id=1000 COREDUMP_ROOT=/ PRIORITY=2 CODE_FILE=src/coredump/coredump.c SYSLOG_IDENTIFIER=lt-systemd-coredump _COMM=lt-systemd-core _SYSTEMD_CGROUP=/user.slice/user-1002.slice/user@1002.service/gnome-terminal-server.service _SYSTEMD_USER_UNIT=gnome-terminal-server.service MESSAGE_ID=1f4e0a44a88649939aaea34fc6da8c95 CODE_FUNC=process_traceback COREDUMP_COMM=python3 COREDUMP_EXE=/usr/bin/python3.5 COREDUMP_CMDLINE=python3 systemd_coredump_exception_handler.py COREDUMP_CWD=/home/zbyszek/src/systemd-coredump-python COREDUMP_RLIMIT=-1 COREDUMP_OPEN_FDS=0:/dev/pts/1 pos: 0 flags: 0102002 mnt_id: 22 1:/dev/pts/1 pos: 0 flags: 0102002 mnt_id: 22 2:/dev/pts/1 pos: 0 flags: 0102002 mnt_id: 22 CODE_LINE=1284 COREDUMP_SIGNAL=ZeroDivisionError: division by zero COREDUMP_ENVIRON=LANG=en_US.utf8 DISPLAY=:0 ... MANWIDTH=90 LC_MESSAGES=en_US.utf8 PYTHONPATH=. _=/usr/bin/python3 COREDUMP_PID=14498 COREDUMP_PROC_STATUS=Name: python3 Umask: 0002 State: S (sleeping) Tgid: 14498 Ngid: 0 Pid: 14498 PPid: 16245 TracerPid: 0 Uid: 1002 1002 1002 1002 Gid: 1002 1002 1002 1002 FDSize: 64 Groups: NStgid: 14498 NSpid: 14498 NSpgid: 14498 NSsid: 16245 VmPeak: 34840 kB VmSize: 34792 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 9332 kB VmRSS: 9332 kB RssAnon: 4872 kB RssFile: 4460 kB RssShmem: 0 kB VmData: 5012 kB VmStk: 136 kB VmExe: 4 kB VmLib: 5452 kB VmPTE: 84 kB VmPMD: 12 kB VmSwap: 0 kB HugetlbPages: 0 kB Threads: 1 SigQ: 0/15413 SigPnd: 0000000000000000 ShdPnd: 0000000000000000 SigBlk: 0000000000000000 SigIgn: 0000000001001000 SigCgt: 0000000180000002 CapInh: 0000000000000000 CapPrm: 0000000000000000 CapEff: 0000000000000000 CapBnd: 0000003fffffffff CapAmb: 0000000000000000 Seccomp: 0 Cpus_allowed: f Cpus_allowed_list: 0-3 Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001 Mems_allowed_list: 0 voluntary_ctxt_switches: 2 nonvoluntary_ctxt_switches: 47 COREDUMP_PROC_MAPS=55cb7b7fe000-55cb7b7ff000 r-xp 00000000 00:1a 5289186 /usr/bin/python3.5 55cb7b9ff000-55cb7ba00000 r--p 00001000 00:1a 5289186 /usr/bin/python3.5 55cb7ba00000-55cb7ba01000 rw-p 00002000 00:1a 5289186 /usr/bin/python3.5 55cb7c007000-55cb7c189000 rw-p 00000000 00:00 0 [heap] 7f4da2d51000-7f4da2d54000 r-xp 00000000 00:1a 5279150 /usr/lib64/python3.5/lib-dynload/resource.cpython-35m-x86_64-linux-gnu.so 7f4da2d54000-7f4da2f53000 ---p 00003000 00:1a 5279150 /usr/lib64/python3.5/lib-dynload/resource.cpython-35m-x86_64-linux-gnu.so 7f4da2f53000-7f4da2f54000 r--p 00002000 00:1a 5279150 /usr/lib64/python3.5/lib-dynload/resource.cpython-35m-x86_64-linux-gnu.so 7f4da2f54000-7f4da2f55000 rw-p 00003000 00:1a 5279150 /usr/lib64/python3.5/lib-dynload/resource.cpython-35m-x86_64-linux-gnu.so 7f4da2f55000-7f4da2f5d000 r-xp 00000000 00:1a 5279143 /usr/lib64/python3.5/lib-dynload/math.cpython-35m-x86_64-linux-gnu.so 7f4da2f5d000-7f4da315c000 ---p 0000800 00:1a 5279143 /usr/lib64/python3.5/lib-dynload/math.cpython-35m-x86_64-linux-gnu.so 7f4da315c000-7f4da315d000 r--p 00007000 00:1a 5279143 /usr/lib64/python3.5/lib-dynload/math.cpython-35m-x86_64-linux-gnu.so 7f4da315d000-7f4da315f000 rw-p 0000800 00:1a 5279143 /usr/lib64/python3.5/lib-dynload/math.cpython-35m-x86_64-linux-gnu.so 7f4da315f000-7f4da319f000 rw-p 00000000 00:00 0 7f4da319f000-7f4da31a4000 r-xp 00000000 00:1a 5279151 /usr/lib64/python3.5/lib-dynload/select.cpython-35m-x86_64-linux-gnu.so 7f4da31a4000-7f4da33a3000 ---p 00005000 00:1a 5279151 /usr/lib64/python3.5/lib-dynload/select.cpython-35m-x86_64-linux-gnu.so 7f4da33a3000-7f4da33a4000 r--p 0000400 00:1a 5279151 /usr/lib64/python3.5/lib-dynload/select.cpython-35m-x86_64-linux-gnu.so 7f4da33a4000-7f4da33a6000 rw-p 00005000 00:1a 5279151 /usr/lib64/python3.5/lib-dynload/select.cpython-35m-x86_64-linux-gnu.so 7f4da33a6000-7f4da33a9000 r-xp 00000000 00:1a 5279130 /usr/lib64/python3.5/lib-dynload/_posixsubprocess.cpython-35m-x86_64-linux-gnu.so 7f4da33a9000-7f4da35a8000 ---p 00003000 00:1a 5279130 /usr/lib64/python3.5/lib-dynload/_posixsubprocess.cpython-35m-x86_64-linux-gnu.so 7f4da35a8000-7f4da35a9000 r--p 00002000 00:1a 5279130 /usr/lib64/python3.5/lib-dynload/_posixsubprocess.cpython-35m-x86_64-linux-gnu.so 7f4da35a9000-7f4da35aa000 rw-p 00003000 00:1a 5279130 /usr/lib64/python3.5/lib-dynload/_posixsubprocess.cpython-35m-x86_64-linux-gnu.so 7f4da35aa000-7f4da362a000 rw-p 00000000 00:00 0 7f4da362a000-7f4da362c000 r-xp 00000000 00:1a 5279122 /usr/lib64/python3.5/lib-dynload/_heapq.cpython-35m-x86_64-linux-gnu.so 7f4da362c000-7f4da382b000 ---p 00002000 00:1a 5279122 /usr/lib64/python3.5/lib-dynload/_heapq.cpython-35m-x86_64-linux-gnu.so 7f4da382b000-7f4da382c000 r--p 00001000 00:1a 5279122 /usr/lib64/python3.5/lib-dynload/_heapq.cpython-35m-x86_64-linux-gnu.so 7f4da382c000-7f4da382e000 rw-p 00002000 00:1a 5279122 /usr/lib64/python3.5/lib-dynload/_heapq.cpython-35m-x86_64-linux-gnu.so 7f4da382e000-7f4da39ee000 rw-p 00000000 00:00 0 7f4da39ee000-7f4da3bab000 r-xp 00000000 00:1a 4844904 /usr/lib64/libc-2.24.so 7f4da3bab000-7f4da3daa000 ---p 001bd000 00:1a 4844904 /usr/lib64/libc-2.24.so 7f4da3daa000-7f4da3dae000 r--p 001bc000 00:1a 4844904 /usr/lib64/libc-2.24.so 7f4da3dae000-7f4da3db0000 rw-p 001c0000 00:1a 4844904 /usr/lib64/libc-2.24.so 7f4da3db0000-7f4da3db4000 rw-p 00000000 00:00 0 7f4da3db4000-7f4da3ebc000 r-xp 00000000 00:1a 4844910 /usr/lib64/libm-2.24.so 7f4da3ebc000-7f4da40bb000 ---p 00108000 00:1a 4844910 /usr/lib64/libm-2.24.so 7f4da40bb000-7f4da40bc000 r--p 00107000 00:1a 4844910 /usr/lib64/libm-2.24.so 7f4da40bc000-7f4da40bd000 rw-p 00108000 00:1a 4844910 /usr/lib64/libm-2.24.so 7f4da40bd000-7f4da40bf000 r-xp 00000000 00:1a 4844928 /usr/lib64/libutil-2.24.so 7f4da40bf000-7f4da42be000 ---p 00002000 00:1a 4844928 /usr/lib64/libutil-2.24.so 7f4da42be000-7f4da42bf000 r--p 00001000 00:1a 4844928 /usr/lib64/libutil-2.24.so 7f4da42bf000-7f4da42c0000 rw-p 00002000 00:1a 4844928 /usr/lib64/libutil-2.24.so 7f4da42c0000-7f4da42c3000 r-xp 00000000 00:1a 4844908 /usr/lib64/libdl-2.24.so 7f4da42c3000-7f4da44c2000 ---p 00003000 00:1a 4844908 /usr/lib64/libdl-2.24.so 7f4da44c2000-7f4da44c3000 r--p 00002000 00:1a 4844908 /usr/lib64/libdl-2.24.so 7f4da44c3000-7f4da44c4000 rw-p 00003000 00:1a 4844908 /usr/lib64/libdl-2.24.so 7f4da44c4000-7f4da44dc000 r-xp 00000000 00:1a 4844920 /usr/lib64/libpthread-2.24.so 7f4da44dc000-7f4da46dc000 ---p 00018000 00:1a 4844920 /usr/lib64/libpthread-2.24.so 7f4da46dc000-7f4da46dd000 r--p 00018000 00:1a 4844920 /usr/lib64/libpthread-2.24.so 7f4da46dd000-7f4da46de000 rw-p 00019000 00:1a 4844920 /usr/lib64/libpthread-2.24.so 7f4da46de000-7f4da46e2000 rw-p 00000000 00:00 0 7f4da46e2000-7f4da4917000 r-xp 00000000 00:1a 5277535 /usr/lib64/libpython3.5m.so.1.0 7f4da4917000-7f4da4b17000 ---p 00235000 00:1a 5277535 /usr/lib64/libpython3.5m.so.1.0 7f4da4b17000-7f4da4b1c000 r--p 00235000 00:1a 5277535 /usr/lib64/libpython3.5m.so.1.0 7f4da4b1c000-7f4da4b7f000 rw-p 0023a000 00:1a 5277535 /usr/lib64/libpython3.5m.so.1.0 7f4da4b7f000-7f4da4baf000 rw-p 00000000 00:00 0 7f4da4baf000-7f4da4bd4000 r-xp 00000000 00:1a 4844897 /usr/lib64/ld-2.24.so 7f4da4bdf000-7f4da4c10000 rw-p 00000000 00:00 0 7f4da4c10000-7f4da4c61000 r--p 00000000 00:1a 5225117 /usr/lib/locale/pl_PL.utf8/LC_CTYPE 7f4da4c61000-7f4da4d91000 r--p 00000000 00:1a 4844827 /usr/lib/locale/en_US.utf8/LC_COLLATE 7f4da4d91000-7f4da4d95000 rw-p 00000000 00:00 0 7f4da4dc1000-7f4da4dc2000 r--p 00000000 00:1a 4844832 /usr/lib/locale/en_US.utf8/LC_NUMERIC 7f4da4dc2000-7f4da4dc3000 r--p 00000000 00:1a 4844795 /usr/lib/locale/en_US.utf8/LC_TIME 7f4da4dc3000-7f4da4dc4000 r--p 00000000 00:1a 4844793 /usr/lib/locale/en_US.utf8/LC_MONETARY 7f4da4dc4000-7f4da4dc5000 r--p 00000000 00:1a 4844830 /usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES 7f4da4dc5000-7f4da4dc6000 r--p 00000000 00:1a 4844847 /usr/lib/locale/en_US.utf8/LC_PAPER 7f4da4dc6000-7f4da4dc7000 r--p 00000000 00:1a 4844831 /usr/lib/locale/en_US.utf8/LC_NAME 7f4da4dc7000-7f4da4dc8000 r--p 00000000 00:1a 4844790 /usr/lib/locale/en_US.utf8/LC_ADDRESS 7f4da4dc8000-7f4da4dc9000 r--p 00000000 00:1a 4844794 /usr/lib/locale/en_US.utf8/LC_TELEPHONE 7f4da4dc9000-7f4da4dca000 r--p 00000000 00:1a 4844792 /usr/lib/locale/en_US.utf8/LC_MEASUREMENT 7f4da4dca000-7f4da4dd1000 r--s 00000000 00:1a 4845203 /usr/lib64/gconv/gconv-modules.cache 7f4da4dd1000-7f4da4dd2000 r--p 00000000 00:1a 4844791 /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION 7f4da4dd2000-7f4da4dd4000 rw-p 00000000 00:00 0 7f4da4dd4000-7f4da4dd5000 r--p 00025000 00:1a 4844897 /usr/lib64/ld-2.24.so 7f4da4dd5000-7f4da4dd6000 rw-p 00026000 00:1a 4844897 /usr/lib64/ld-2.24.so 7f4da4dd6000-7f4da4dd7000 rw-p 00000000 00:00 0 7ffd24da1000-7ffd24dc2000 rw-p 00000000 00:00 0 [stack] 7ffd24de8000-7ffd24dea000 r--p 00000000 00:00 0 [vvar] 7ffd24dea000-7ffd24dec000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] COREDUMP_TIMESTAMP=1477877460000000 MESSAGE=Process 14498 (python3) of user 1002 failed with ZeroDivisionError: division by zero: Traceback (most recent call last): File "systemd_coredump_exception_handler.py", line 89, in <module> g() File "systemd_coredump_exception_handler.py", line 88, in g f() File "systemd_coredump_exception_handler.py", line 86, in f div0 = 1 / 0 # pylint: disable=W0612 ZeroDivisionError: division by zero Local variables in innermost frame: h=<function f at 0x7f4da3606e18> a=3 _PID=14499 _SOURCE_REALTIME_TIMESTAMP=1477877460025975
1 parent 9aa8202 commit 988e89e

File tree

3 files changed

+91
-9
lines changed

3 files changed

+91
-9
lines changed

man/coredump.conf.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585

8686
<listitem><para>Controls where to store cores. One of <literal>none</literal>,
8787
<literal>external</literal>, and <literal>journal</literal>. When
88-
<literal>none</literal>, the core dumps will be logged (included the traceback if
88+
<literal>none</literal>, the core dumps will be logged (including the backtrace if
8989
possible), but not stored permanently. When <literal>external</literal> (the
9090
default), cores will be stored in <filename>/var/lib/systemd/coredump/</filename>.
9191
When <literal>journal</literal>, cores will be stored in the journal and rotated

src/coredump/coredump.c

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,8 @@ static int process_socket(int fd) {
830830
log_parse_environment();
831831
log_open();
832832

833+
log_debug("Processing coredump received on stdin...");
834+
833835
for (;;) {
834836
union {
835837
struct cmsghdr cmsghdr;
@@ -1045,6 +1047,7 @@ static char* set_iovec_field_free(struct iovec iovec[27], size_t *n_iovec, const
10451047
static int gather_pid_metadata(
10461048
const char *context[_CONTEXT_MAX],
10471049
char **comm_fallback,
1050+
char **comm_ret,
10481051
struct iovec iovec[27], size_t *n_iovec) {
10491052

10501053
_cleanup_free_ char *exe = NULL, *comm = NULL;
@@ -1056,7 +1059,7 @@ static int gather_pid_metadata(
10561059

10571060
r = parse_pid(context[CONTEXT_PID], &pid);
10581061
if (r < 0)
1059-
return log_error_errno(r, "Failed to parse PID.");
1062+
return log_error_errno(r, "Failed to parse PID \"%s\": %m", context[CONTEXT_PID]);
10601063

10611064
r = get_process_comm(pid, &comm);
10621065
if (r < 0) {
@@ -1182,18 +1185,25 @@ static int gather_pid_metadata(
11821185
if (t)
11831186
IOVEC_SET_STRING(iovec[(*n_iovec)++], t);
11841187

1188+
if (comm_ret) {
1189+
*comm_ret = comm;
1190+
comm = NULL;
1191+
}
1192+
11851193
return 0;
11861194
}
11871195

11881196
static int process_kernel(int argc, char* argv[]) {
11891197

11901198
const char *context[_CONTEXT_MAX];
11911199
struct iovec iovec[27];
1192-
size_t n_iovec = 0, i, n_to_free;
1200+
size_t i, n_iovec, n_to_free = 0;
11931201
int r;
11941202

1203+
log_debug("Processing coredump received from the kernel...");
1204+
11951205
if (argc < CONTEXT_COMM + 1) {
1196-
log_error("Not enough arguments passed from kernel (%i, expected %i).", argc - 1, CONTEXT_COMM + 1 - 1);
1206+
log_error("Not enough arguments passed by the kernel (%i, expected %i).", argc - 1, CONTEXT_COMM + 1 - 1);
11971207
return -EINVAL;
11981208
}
11991209

@@ -1204,10 +1214,10 @@ static int process_kernel(int argc, char* argv[]) {
12041214
context[CONTEXT_TIMESTAMP] = argv[CONTEXT_TIMESTAMP + 1];
12051215
context[CONTEXT_RLIMIT] = argv[CONTEXT_RLIMIT + 1];
12061216

1207-
r = gather_pid_metadata(context, argv + CONTEXT_COMM + 1, iovec, &n_iovec);
1217+
r = gather_pid_metadata(context, argv + CONTEXT_COMM + 1, NULL, iovec, &n_to_free);
12081218
if (r < 0)
12091219
goto finish;
1210-
n_to_free = n_iovec;
1220+
n_iovec = n_to_free;
12111221

12121222
IOVEC_SET_STRING(iovec[n_iovec++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1");
12131223

@@ -1225,6 +1235,74 @@ static int process_kernel(int argc, char* argv[]) {
12251235
return r;
12261236
}
12271237

1238+
static int process_backtrace(int argc, char *argv[]) {
1239+
const char *context[_CONTEXT_MAX];
1240+
char *t;
1241+
_cleanup_free_ char *comm = NULL;
1242+
struct iovec iovec[27];
1243+
size_t n_iovec = 0, i, n_to_free;
1244+
uint8_t buf[4096];
1245+
ssize_t buf_bytes;
1246+
int r;
1247+
1248+
log_debug("Processing backtrace on stdin...");
1249+
1250+
if (argc < CONTEXT_COMM + 1) {
1251+
log_error("Not enough arguments passed (%i, expected %i).", argc - 1, CONTEXT_COMM + 1 - 1);
1252+
return -EINVAL;
1253+
}
1254+
1255+
context[CONTEXT_PID] = argv[CONTEXT_PID + 2];
1256+
context[CONTEXT_UID] = argv[CONTEXT_UID + 2];
1257+
context[CONTEXT_GID] = argv[CONTEXT_GID + 2];
1258+
context[CONTEXT_SIGNAL] = argv[CONTEXT_SIGNAL + 2];
1259+
context[CONTEXT_TIMESTAMP] = argv[CONTEXT_TIMESTAMP + 2];
1260+
context[CONTEXT_RLIMIT] = argv[CONTEXT_RLIMIT + 2];
1261+
1262+
r = gather_pid_metadata(context, argv + CONTEXT_COMM + 2, &comm, iovec, &n_iovec);
1263+
if (r < 0)
1264+
goto finish;
1265+
1266+
if (isempty(context[CONTEXT_SIGNAL]))
1267+
context[CONTEXT_SIGNAL] = "an exception";
1268+
1269+
buf_bytes = loop_read(STDIN_FILENO, buf, sizeof(buf) - 1, false);
1270+
if (buf_bytes < 0) {
1271+
log_error_errno(buf_bytes, "Failed to read backtrace from stdin: %m");
1272+
goto finish;
1273+
}
1274+
buf[buf_bytes] = '\0';
1275+
1276+
t = strjoin("MESSAGE=Process ", context[CONTEXT_PID], " (", comm, ")"
1277+
" of user ", context[CONTEXT_UID],
1278+
" failed with ", context[CONTEXT_SIGNAL],
1279+
":\n\n", buf, NULL);
1280+
if (!t) {
1281+
log_oom();
1282+
goto finish;
1283+
}
1284+
IOVEC_SET_STRING(iovec[n_iovec++], t);
1285+
1286+
n_to_free = n_iovec;
1287+
1288+
IOVEC_SET_STRING(iovec[n_iovec++], "MESSAGE_ID=1f4e0a44a88649939aaea34fc6da8c95");
1289+
1290+
assert_cc(2 == LOG_CRIT);
1291+
IOVEC_SET_STRING(iovec[n_iovec++], "PRIORITY=2");
1292+
1293+
assert(n_iovec <= ELEMENTSOF(iovec));
1294+
1295+
r = sd_journal_sendv(iovec, n_iovec);
1296+
if (r < 0)
1297+
log_error_errno(r, "Failed to log backtrace: %m");
1298+
1299+
finish:
1300+
for (i = 0; i < n_to_free; i++)
1301+
free(iovec[i].iov_base);
1302+
1303+
return r;
1304+
}
1305+
12281306
int main(int argc, char *argv[]) {
12291307
int r;
12301308

@@ -1251,9 +1329,12 @@ int main(int argc, char *argv[]) {
12511329

12521330
/* If we got an fd passed, we are running in coredumpd mode. Otherwise we
12531331
* are invoked from the kernel as coredump handler. */
1254-
if (r == 0)
1255-
r = process_kernel(argc, argv);
1256-
else if (r == 1)
1332+
if (r == 0) {
1333+
if (streq_ptr(argv[1], "--backtrace"))
1334+
r = process_backtrace(argc, argv);
1335+
else
1336+
r = process_kernel(argc, argv);
1337+
} else if (r == 1)
12571338
r = process_socket(SD_LISTEN_FDS_START);
12581339
else {
12591340
log_error("Received unexpected number of file descriptors.");

src/systemd/sd-messages.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ _SD_BEGIN_DECLARATIONS;
4141

4242
#define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1)
4343
#define SD_MESSAGE_TRUNCATED_CORE SD_ID128_MAKE(5a,ad,d8,e9,54,dc,4b,1a,8c,95,4d,63,fd,9e,11,37)
44+
#define SD_MESSAGE_BACKTRACE SD_ID128_MAKE(1f,4e,0a,44,a8,86,49,93,9a,ae,a3,4f,c6,da,8c,95)
4445

4546
#define SD_MESSAGE_SESSION_START SD_ID128_MAKE(8d,45,62,0c,1a,43,48,db,b1,74,10,da,57,c6,0c,66)
4647
#define SD_MESSAGE_SESSION_STOP SD_ID128_MAKE(33,54,93,94,24,b4,45,6d,98,02,ca,83,33,ed,42,4a)

0 commit comments

Comments
 (0)