The /proc/PID/coredump_filter mechanism makes it easy to tweak the
per-process setting to control ELF core dump style details.
This setting is per-process (per-mm) and inherited by children.
But as a user, the /proc interface is insane. It prints a magical hex
value (without a leading 0x, to make it sneaky), which you'll be damn lucky
to figure out from reading Documentation/filesystems/proc.txt. Then you
get to set it to another such magical value, which is in decimal unless you
add a leading 0x (cat /proc/x/coredump_filter > /proc/y/coredump_filter
does not copy the setting, go team).
I have kicking around this half-assed bash script that I don't care to
bother making really presentable. Where should it live? In the upstream
kernel's scripts/? (Then noone would ever see it for sure.)
In util-linux-ng? Or what? Someone want to take it off my hands?
Thanks,
Roland
#!/bin/bash
#
# Usage: chcorefilter - PID... prints [pmfse]+ string for each PID
# chcorefilter [pmfse]+ PID... changes filter bits for each PID
#
# Each bit set says a flavor of mapping that should be included in core dumps.
# The setting for a process is inherited by its new children.
#
# p anonymous Private memory
# m anonymous shared Memory
# f private File mapping
# s Shared file mapping
# e ELF headers (first page of ELF-looking untouched file mapping)
#
# Default setting upstream is 'pm', Fedora >= 8 default is 'pme'.
# GDB < 6.7 will be confused by the core files from +e settings.
#
# A fancier command would take +e or -e to set/clear just some
# bits relative to the current setting.
#
get_filter()
{
local pid=$1
local f
f=`cat /proc/$pid/coredump_filter` || exit
((f=0x$f))
local s=''
((($f & 1) == 0)) || s="${s}p"
((($f & 2) == 0)) || s="${s}m"
((($f & 4) == 0)) || s="${s}f"
((($f & 8) == 0)) || s="${s}s"
((($f & 16) == 0)) || s="${s}e"
filter_dec=$f
filter_str=${s:-.}
}
set_filter()
{
local pid=$1
local val=$2
printf "0x%x\n" $val > /proc/$pid/coredump_filter || exit
}
if [ $# -eq 0 ]; then
exec sed '1d;/^#/!q' $0
fi
if [ "x$1" = x- ]; then
shift
for pid; do
get_filter $pid
if [ $# -gt 1 ]; then
echo "${pid}: ${filter_str}"
else
echo "$filter_str"
fi
done
exit 0
fi
arg="$1"
shift
case "$arg" in
-*) op='&=~'; arg=${arg#?} ;;
+*) op='|=' ; arg=${arg#?} ;;
.) op='=' ; arg=${arg#?} ;;
*) op='=' ;;
esac
val=0
until [ -z "$arg" ]; do
case "$arg" in
p*) ((val |= 1));; # anonymous Private memory
m*) ((val |= 2));; # anonymous shared Memory
f*) ((val |= 4));; # private File mapping
s*) ((val |= 8));; # Shared file mapping
e*) ((val |= 16));; # ELF headers
*) bogon; break ;;
esac
arg=${arg#?}
done
for pid; do
get_filter $pid
((filter_dec $op $val))
set_filter $pid $filter_dec
done
Show replies by date