Files
kata-containers/tests/error.sh
Fabiano Fidêncio 138637fa47 tests: Fix shellcheck issues in error.sh
Fix shellcheck warnings and notes identified by running
shellcheck --severity=style.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
2026-04-24 08:14:07 +02:00

219 lines
4.1 KiB
Bash

#!/usr/bin/env bash
#
# Copyright (c) 2022-2024 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
# Description: Error handling functions.
# Write specified message to stderr.
stderr()
{
local msg="$*"
echo >&2 "${msg}"
}
# Simplified version of die that should be called by functions that
# could fail as part of the normal "die()" code path. Required to
# avoid infinite recursion.
_fatal()
{
local msg="$*"
echo >&2 "FATAL: ${msg}"
exit 1
}
# Canonicalize the specified path (which must be valid).
resolve_path()
{
local file="${1:-}"
[[ -z "${file}" ]] && _fatal "need file to resolve"
local path
path=$(readlink --canonicalize-existing "${file}" || \
_fatal "failed to resolve file '${file}'")
echo "${path}"
}
show_proc_hierarchy()
{
local pid="${$}"
local details
stderr "process-hierarchy:"
local -i i
for ((i=0; ; i++))
do
local details
local msg
local current=''
[[ "${pid}" = "${$}" ]] && current=", current='yes'"
details=$(ps --no-headers -p "${pid}" -o ppid,cmd)
local ppid
ppid=$(echo "${details}" | awk '{print $1}')
local cmd
cmd=$(echo "${details}" |\
awk '{$1=""; print $0}' |\
sed \
-e 's/^ *//g' \
-e 's/ *$//g')
msg=$(printf " %d: {pid: %d, command: '%s'%s}" \
"${i}" \
"${pid}" \
"${cmd}" \
"${current}")
stderr "${msg}"
[[ "${pid}" = 1 ]] && break
pid="${ppid}"
done
}
show_stacktrace()
{
local err_line="${1:-}"
local err_func="${2:-}"
local err_path="${3:-}"
[[ -z "${err_line}" ]] && _fatal "need error location line number"
[[ -z "${err_func}" ]] && _fatal "need error location func"
[[ -z "${err_path}" ]] && _fatal "need error location file path"
local line
local func
local file
local -i i
stderr "stacktrace:"
for ((i = 0; ; i++))
do
local result
result=$(caller "${i}" || true)
[[ -z "${result}" ]] && break
line=$(echo "${result}"|awk '{print $1}')
func=$(echo "${result}"|awk '{print $2}')
file=$(echo "${result}"|awk '{print $3}')
local path
path=$(resolve_path "${file}")
local msg
local current=''
# Add a visual marker showing where the original error was
# detected.
[[ "${line}" = "${err_line}" ]] && \
[[ "${func}" = "${err_func}" ]] && \
[[ "${path}" = "${err_path}" ]] && \
current=", current='yes'"
msg=$(printf " %d: {function: '%s', file: '%s', line: %d%s}\n" \
"${i}" \
"${func}" \
"${path}" \
"${line}" \
"${current}" )
stderr "${msg}"
done
}
# Function to be called by die() or a trap/signal handler to dump all
# details of the environment (in YAML format), to help with debugging.
dump_details()
{
set +x
local err_line="${1:-}"
local err_func="${2:-}"
local err_path="${3:-}"
[[ -z "${err_line}" ]] && _fatal "need error location line number"
[[ -z "${err_func}" ]] && _fatal "need error location func"
[[ -z "${err_path}" ]] && _fatal "need error location file path"
# Spacer
stderr
stderr "script:"
stderr " name: '$0'"
stderr " pid: $$"
stderr " directory: '${PWD}'"
stderr " details: '$(ls -dlZ "${PWD}")'"
stderr "failure:"
stderr " function: '${func}'"
stderr " file: '${path}'"
stderr " line: ${line}"
stderr " name: '$0'"
show_stacktrace \
"${err_line}" \
"${err_func}" \
"${err_path}"
show_proc_hierarchy
stderr "time: '$(date -Isec)'"
stderr "runtime-seconds: ${SECONDS}"
stderr "host:"
stderr " name: '$(hostname)'"
stderr " uname: '$(uname -a)'"
stderr "locale:"
locale 2>/dev/null | sed \
-e 's/^/ /g' \
-e 's/=/: '\''/g' \
-e 's/$/'\''/g' \
>&2
stderr "user:"
stderr " uid: {value: ${UID}, name: '$(getent passwd "${UID}"|cut -d: -f1)'}"
stderr " euid: {value: ${EUID} , name: '$(getent passwd "${EUID}"|cut -d: -f1)'}"
stderr " groups: '$(id)'"
stderr "bash:"
stderr " version: '${BASH_VERSION}'"
stderr " version-info: '${BASH_VERSINFO[*]}'"
stderr "environment:"
# Remove bash functions (that can span multiple lines)
env |\
grep -v "^BASH_FUNC" |\
grep -Ei "^[a-z_][a-z0-9_]+=" |\
sort -t '=' -k1 |\
sed \
-e 's/^/ /g' \
-e 's/=/: '\''/' \
-e 's/$/'\''/g' \
>&2
stderr "mounts: |"
mount | sed 's/^/ /g' >&2
stderr "processes: |"
ps -eF | sed 's/^/ /g' >&2
# Spacer
stderr
}