1#!/usr/bin/env bash 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright (C) 2020 Intel Corporation 4# All rights reserved. 5# 6# We don't want to tell kernel to include %e or %E since these 7# can include whitespaces or other funny characters, and working 8# with those on the cmdline would be a nightmare. Use procfs for 9# the remaining pieces we want to gather: 10# |$rootdir/scripts/core-collector.sh %P %s %t $output_dir 11 12core_meta() { 13 jq . <<- CORE 14 { 15 "$exe_comm": { 16 "ts": "$core_time", 17 "size": "$core_size bytes", 18 "PID": $core_pid, 19 "signal": "$core_sig ($core_sig_name)", 20 "path": "$exe_path", 21 "statm": "$statm", 22 "filter": "$(coredump_filter)" 23 } 24 } 25 CORE 26} 27 28bt() { hash gdb && gdb -batch -ex "thread apply all bt full" "$1" "$2" 2>&1; } 29 30stderr() { 31 exec 2> "$core.stderr.txt" 32 set -x 33} 34 35coredump_filter() { 36 local bitmap bit 37 local _filter filter 38 39 bitmap[0]=anon-priv-mappings 40 bitmap[1]=anon-shared-mappings 41 bitmap[2]=file-priv-mappings 42 bitmap[3]=file-shared-mappings 43 bitmap[4]=elf-headers 44 bitmap[5]=priv-hp 45 bitmap[6]=shared-hp 46 bitmap[7]=priv-DAX 47 bitmap[8]=shared-DAX 48 49 _filter=0x$(< "/proc/$core_pid/coredump_filter") 50 51 for bit in "${!bitmap[@]}"; do 52 ((_filter & 1 << bit)) || continue 53 filter=${filter:+$filter,}${bitmap[bit]} 54 done 55 56 echo "$filter" 57} 58 59args+=(core_pid) 60args+=(core_sig) 61args+=(core_ts) 62 63read -r "${args[@]}" <<< "$*" 64 65exe_path=$(readlink -f "/proc/$core_pid/exe") 66exe_comm=$(< "/proc/$core_pid/comm") 67statm=$(< "/proc/$core_pid/statm") 68core_time=$(date -d@"$core_ts") 69core_sig_name=$(kill -l "$core_sig") 70 71core=$(< "${0%/*}/../.coredump_path")/${exe_path##*/}_$core_pid.core 72stderr 73 74# RLIMIT_CORE is not enforced when core is piped to us. To make 75# sure we won't attempt to overload underlying storage, copy 76# only the reasonable amount of bytes (systemd defaults to 2G 77# so let's follow that). 78rlimit=$((1024 * 1024 * 1024 * 2)) 79 80# Clear path for lz 81rm -f "$core"{,.{bin,bt,gz,json}} 82 83# Slurp the core 84head -c "$rlimit" <&0 > "$core" 85core_size=$(wc -c < "$core") 86 87# Compress it 88gzip -c "$core" > "$core.gz" 89 90# Save the binary 91cp "$exe_path" "$core.bin" 92 93# Save the backtrace 94bt "$exe_path" "$core" > "$core.bt.txt" 95 96# Save the metadata of the core 97core_meta > "$core.json" 98 99# Nuke the original core 100rm "$core" 101