hwdb: fix screen rotation for EXO Wings 2in1 w1125 (#36283)
[systemd.io.git] / test / units / TEST-87-AUX-UTILS-VM.coredump.sh
blob7ab6f29d7d5ee44dd935a454653f35c561986142
1 #!/usr/bin/env bash
2 # SPDX-License-Identifier: LGPL-2.1-or-later
3 set -eux
4 set -o pipefail
6 # shellcheck source=test/units/util.sh
7 . "$(dirname "$0")"/util.sh
9 # Make sure the binary name fits into 15 characters
10 CORE_TEST_BIN="/tmp/test-dump"
11 CORE_STACKTRACE_TEST_BIN="/tmp/test-stacktrace-dump"
12 MAKE_STACKTRACE_DUMP="/tmp/make-stacktrace-dump"
13 CORE_TEST_UNPRIV_BIN="/tmp/test-usr-dump"
14 MAKE_DUMP_SCRIPT="/tmp/make-dump"
15 # Unset $PAGER so we don't have to use --no-pager everywhere
16 export PAGER=
18 at_exit() {
19 rm -fv -- "$CORE_TEST_BIN" "$CORE_TEST_UNPRIV_BIN" "$MAKE_DUMP_SCRIPT" "$MAKE_STACKTRACE_DUMP"
22 (! systemd-detect-virt -cq)
24 trap at_exit EXIT
26 # To make all coredump entries stored in system.journal.
27 journalctl --rotate
29 # Check that we're the ones to receive coredumps
30 sysctl kernel.core_pattern | grep systemd-coredump
32 # Prepare "fake" binaries for coredumps, so we can properly exercise
33 # the matching stuff too
34 cp -vf /bin/sleep "${CORE_TEST_BIN:?}"
35 cp -vf /bin/sleep "${CORE_TEST_UNPRIV_BIN:?}"
36 # Simple script that spawns given "fake" binary and then kills it with
37 # given signal
38 cat >"${MAKE_DUMP_SCRIPT:?}" <<\EOF
39 #!/bin/bash -ex
41 bin="${1:?}"
42 sig="${2:?}"
44 ulimit -c unlimited
45 "$bin" infinity &
46 pid=$!
47 # Sync with the "fake" binary, so we kill it once it's fully forked off,
48 # otherwise we might kill it during fork and kernel would then report
49 # "wrong" binary name (i.e. $MAKE_DUMP_SCRIPT instead of $CORE_TEST_BIN).
50 # In this case, wait until the "fake" binary (sleep in this case) enters
51 # the "interruptible sleep" state, at which point it should be ready
52 # to be sacrificed.
53 for _ in {0..9}; do
54 read -ra self_stat <"/proc/$pid/stat"
55 [[ "${self_stat[2]}" == S ]] && break
56 sleep .5
57 done
58 kill -s "$sig" "$pid"
59 # This should always fail
60 ! wait "$pid"
61 EOF
62 chmod +x "$MAKE_DUMP_SCRIPT"
64 # Privileged stuff
65 [[ "$(id -u)" -eq 0 ]]
66 # Trigger a couple of coredumps
67 "$MAKE_DUMP_SCRIPT" "$CORE_TEST_BIN" "SIGTRAP"
68 "$MAKE_DUMP_SCRIPT" "$CORE_TEST_BIN" "SIGABRT"
69 # In the tests we store the coredumps in journals, so let's generate a couple
70 # with Storage=external as well
71 mkdir -p /run/systemd/coredump.conf.d/
72 printf '[Coredump]\nStorage=external' >/run/systemd/coredump.conf.d/99-external.conf
73 "$MAKE_DUMP_SCRIPT" "$CORE_TEST_BIN" "SIGTRAP"
74 "$MAKE_DUMP_SCRIPT" "$CORE_TEST_BIN" "SIGABRT"
75 rm -fv /run/systemd/coredump.conf.d/99-external.conf
76 # Wait a bit for the coredumps to get processed
77 timeout 30 bash -c "while [[ \$(coredumpctl list -q --no-legend $CORE_TEST_BIN | wc -l) -lt 4 ]]; do sleep 1; done"
79 if cgroupfs_supports_user_xattrs; then
80 # Make sure we can forward crashes back to containers
81 CONTAINER="TEST-87-AUX-UTILS-VM-container"
83 mkdir -p "/var/lib/machines/$CONTAINER"
84 mkdir -p "/run/systemd/system/systemd-nspawn@$CONTAINER.service.d"
85 # Bind-mounting /etc into the container kinda defeats the purpose of --volatile=,
86 # but we need the ASan-related overrides scattered across /etc
87 cat > "/run/systemd/system/systemd-nspawn@$CONTAINER.service.d/override.conf" <<EOF
88 [Service]
89 ExecStart=
90 ExecStart=systemd-nspawn --quiet --link-journal=try-guest --keep-unit --machine=%i --boot \
91 --volatile=yes --directory=/ --bind-ro=/etc --inaccessible=/etc/machine-id
92 EOF
93 systemctl daemon-reload
95 [[ "$(systemd-detect-virt)" == "qemu" ]] && TIMEOUT=120 || TIMEOUT=60
97 machinectl start "$CONTAINER"
98 timeout "$TIMEOUT" bash -xec "until systemd-run -M '$CONTAINER' -q --wait --pipe true; do sleep .5; done"
100 [[ "$(systemd-run -M "$CONTAINER" -q --wait --pipe coredumpctl list -q --no-legend /usr/bin/sleep | wc -l)" -eq 0 ]]
101 machinectl copy-to "$CONTAINER" "$MAKE_DUMP_SCRIPT"
102 systemd-run -M "$CONTAINER" -q --wait --pipe "$MAKE_DUMP_SCRIPT" "/usr/bin/sleep" "SIGABRT"
103 systemd-run -M "$CONTAINER" -q --wait --pipe "$MAKE_DUMP_SCRIPT" "/usr/bin/sleep" "SIGTRAP"
104 # Wait a bit for the coredumps to get processed
105 timeout 30 bash -c "while [[ \$(systemd-run -M $CONTAINER -q --wait --pipe coredumpctl list -q --no-legend /usr/bin/sleep | wc -l) -lt 2 ]]; do sleep 1; done"
107 machinectl stop "$CONTAINER"
108 rm -rf "/var/lib/machines/$CONTAINER"
109 unset CONTAINER
112 coredumpctl
113 SYSTEMD_LOG_LEVEL=debug coredumpctl
114 coredumpctl --help
115 coredumpctl --version
116 coredumpctl --no-pager --no-legend
117 coredumpctl --all
118 coredumpctl -1
119 coredumpctl -n 1
120 coredumpctl --reverse
121 coredumpctl -F COREDUMP_EXE
122 coredumpctl --json=short | jq
123 coredumpctl --json=pretty | jq
124 coredumpctl --json=off
125 coredumpctl --root=/
126 coredumpctl --directory=/var/log/journal
127 coredumpctl --file="/var/log/journal/$(</etc/machine-id)"/*.journal
128 coredumpctl --since=@0
129 coredumpctl --since=yesterday --until=tomorrow
130 # We should have a couple of externally stored coredumps
131 coredumpctl --field=COREDUMP_FILENAME | tee /tmp/coredumpctl.out
132 grep "/var/lib/systemd/coredump/core" /tmp/coredumpctl.out
133 rm -f /tmp/coredumpctl.out
135 coredumpctl info
136 coredumpctl info "$CORE_TEST_BIN"
137 coredumpctl info /foo /bar/ /baz "$CORE_TEST_BIN"
138 coredumpctl info "${CORE_TEST_BIN##*/}"
139 coredumpctl info foo bar baz "${CORE_TEST_BIN##*/}"
140 coredumpctl info COREDUMP_EXE="$CORE_TEST_BIN"
141 coredumpctl info COREDUMP_EXE=aaaaa COREDUMP_EXE= COREDUMP_EXE="$CORE_TEST_BIN"
143 coredumpctl debug --debugger=/bin/true "$CORE_TEST_BIN"
144 SYSTEMD_DEBUGGER=/bin/true coredumpctl debug "$CORE_TEST_BIN"
145 coredumpctl debug --debugger=/bin/true --debugger-arguments="-this --does --not 'do anything' -a -t --all" "${CORE_TEST_BIN##*/}"
147 coredumpctl dump "$CORE_TEST_BIN" >/tmp/core.redirected
148 test -s /tmp/core.redirected
149 coredumpctl dump -o /tmp/core.output "${CORE_TEST_BIN##*/}"
150 test -s /tmp/core.output
151 rm -f /tmp/core.{output,redirected}
153 # Unprivileged stuff
154 # Related issue: https://github.com/systemd/systemd/issues/26912
155 UNPRIV_CMD=(systemd-run --user --wait --pipe -M "testuser@.host" --)
156 # Trigger a couple of coredumps as an unprivileged user
157 "${UNPRIV_CMD[@]}" "$MAKE_DUMP_SCRIPT" "$CORE_TEST_UNPRIV_BIN" "SIGTRAP"
158 "${UNPRIV_CMD[@]}" "$MAKE_DUMP_SCRIPT" "$CORE_TEST_UNPRIV_BIN" "SIGABRT"
159 # In the tests we store the coredumps in journals, so let's generate a couple
160 # with Storage=external as well
161 mkdir -p /run/systemd/coredump.conf.d/
162 printf '[Coredump]\nStorage=external' >/run/systemd/coredump.conf.d/99-external.conf
163 "${UNPRIV_CMD[@]}" "$MAKE_DUMP_SCRIPT" "$CORE_TEST_UNPRIV_BIN" "SIGTRAP"
164 "${UNPRIV_CMD[@]}" "$MAKE_DUMP_SCRIPT" "$CORE_TEST_UNPRIV_BIN" "SIGABRT"
165 rm -fv /run/systemd/coredump.conf.d/99-external.conf
166 # Wait a bit for the coredumps to get processed
167 timeout 30 bash -c "while [[ \$(coredumpctl list -q --no-legend $CORE_TEST_UNPRIV_BIN | wc -l) -lt 4 ]]; do sleep 1; done"
169 # root should see coredumps from both binaries
170 coredumpctl info "$CORE_TEST_UNPRIV_BIN"
171 coredumpctl info "${CORE_TEST_UNPRIV_BIN##*/}"
172 # The test user should see only their own coredumps
173 "${UNPRIV_CMD[@]}" coredumpctl
174 "${UNPRIV_CMD[@]}" coredumpctl info "$CORE_TEST_UNPRIV_BIN"
175 "${UNPRIV_CMD[@]}" coredumpctl info "${CORE_TEST_UNPRIV_BIN##*/}"
176 (! "${UNPRIV_CMD[@]}" coredumpctl info --all "$CORE_TEST_BIN")
177 (! "${UNPRIV_CMD[@]}" coredumpctl info --all "${CORE_TEST_BIN##*/}")
178 # We should have a couple of externally stored coredumps
179 "${UNPRIV_CMD[@]}" coredumpctl --field=COREDUMP_FILENAME | tee /tmp/coredumpctl.out
180 grep "/var/lib/systemd/coredump/core" /tmp/coredumpctl.out
181 rm -f /tmp/coredumpctl.out
183 "${UNPRIV_CMD[@]}" coredumpctl debug --debugger=/bin/true "$CORE_TEST_UNPRIV_BIN"
184 "${UNPRIV_CMD[@]}" coredumpctl debug --debugger=/bin/true --debugger-arguments="-this --does --not 'do anything' -a -t --all" "${CORE_TEST_UNPRIV_BIN##*/}"
186 "${UNPRIV_CMD[@]}" coredumpctl dump "$CORE_TEST_UNPRIV_BIN" >/tmp/core.redirected
187 test -s /tmp/core.redirected
188 "${UNPRIV_CMD[@]}" coredumpctl dump -o /tmp/core.output "${CORE_TEST_UNPRIV_BIN##*/}"
189 test -s /tmp/core.output
190 rm -f /tmp/core.{output,redirected}
191 (! "${UNPRIV_CMD[@]}" coredumpctl dump "$CORE_TEST_BIN" >/dev/null)
193 # --backtrace mode
194 # Pass one of the existing journal coredump records to systemd-coredump and
195 # use our PID as the source to make matching the coredump later easier
196 # systemd-coredump args: PID UID GID SIGNUM TIMESTAMP CORE_SOFT_RLIMIT HOSTNAME
197 journalctl -b -n 1 --output=export --output-fields=MESSAGE,COREDUMP COREDUMP_EXE="/usr/bin/test-dump" |
198 /usr/lib/systemd/systemd-coredump --backtrace $$ 0 0 6 1679509994 12345 mymachine
199 # Wait a bit for the coredump to get processed
200 timeout 30 bash -c "while [[ \$(coredumpctl list -q --no-legend $$ | wc -l) -eq 0 ]]; do sleep 1; done"
201 coredumpctl info "$$"
202 coredumpctl info COREDUMP_HOSTNAME="mymachine"
204 # This used to cause a stack overflow
205 systemd-run -t --property CoredumpFilter=all ls /tmp
206 systemd-run -t --property CoredumpFilter=default ls /tmp
208 (! coredumpctl --hello-world)
209 (! coredumpctl -n 0)
210 (! coredumpctl -n -1)
211 (! coredumpctl --file=/dev/null)
212 (! coredumpctl --since=0)
213 (! coredumpctl --until='')
214 (! coredumpctl --since=today --until=yesterday)
215 (! coredumpctl --directory=/ --root=/)
216 (! coredumpctl --json=foo)
217 (! coredumpctl -F foo -F bar)
218 (! coredumpctl list 0)
219 (! coredumpctl list -- -1)
220 (! coredumpctl list '')
221 (! coredumpctl info /../.~=)
222 (! coredumpctl info '')
223 (! coredumpctl dump --output=/dev/full "$CORE_TEST_BIN")
224 (! coredumpctl dump --output=/dev/null --output=/dev/null "$CORE_TEST_BIN")
225 (! coredumpctl debug --debugger=/bin/false)
226 (! coredumpctl debug --debugger=/bin/true --debugger-arguments='"')
228 # Test for EnterNamespace= feature
229 if pkgconf --atleast-version 0.192 libdw ; then
230 # dwfl_set_sysroot() is supported only in libdw-0.192 or newer.
231 cat >"$MAKE_STACKTRACE_DUMP" <<END
232 #!/bin/bash
233 mount -t tmpfs tmpfs /tmp
234 gcc -xc -O0 -g -o $CORE_STACKTRACE_TEST_BIN - <<EOF
235 void baz(void) { int *x = 0; *x = 42; }
236 void bar(void) { baz(); }
237 void foo(void) { bar(); }
238 int main(void) { foo(); return 0;}
240 $CORE_STACKTRACE_TEST_BIN
242 chmod +x "$MAKE_STACKTRACE_DUMP"
244 mkdir -p /run/systemd/coredump.conf.d/
245 printf '[Coredump]\nEnterNamespace=no' >/run/systemd/coredump.conf.d/99-enter-namespace.conf
247 unshare --pid --fork --mount-proc --mount --uts --ipc --net /bin/bash -c "$MAKE_STACKTRACE_DUMP" || :
248 timeout 30 bash -c "until coredumpctl -1 info $CORE_STACKTRACE_TEST_BIN | grep -zvqE 'baz.*bar.*foo'; do sleep .2; done"
250 printf '[Coredump]\nEnterNamespace=yes' >/run/systemd/coredump.conf.d/99-enter-namespace.conf
251 unshare --pid --fork --mount-proc --mount --uts --ipc --net /bin/bash -c "$MAKE_STACKTRACE_DUMP" || :
252 timeout 30 bash -c "until coredumpctl -1 info $CORE_STACKTRACE_TEST_BIN | grep -zqE 'baz.*bar.*foo'; do sleep .2; done"
253 else
254 echo "libdw doesn't not support setting sysroot, skipping EnterNamespace= test"