167 lines
4.6 KiB
Bash
Executable File
167 lines
4.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
############################################################################
|
|
# tools/btdecode.sh
|
|
#
|
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright ownership. The
|
|
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance with the
|
|
# License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
#
|
|
############################################################################
|
|
|
|
# This script can be used to decode the backtrace that's dumped on assertions.
|
|
#
|
|
# On assertions we can find the raw backtrace dump similar to:
|
|
# ...
|
|
# sched_dumpstack: backtrace| 0: 0x400e1a2a 0x40082912
|
|
# sched_dumpstack: backtrace| 1: 0x400e39ac 0x400ef7c3 0x400ef7fc 0x400e8116 0x400e7910 0x400e7be8 0x400e6c5c 0x400e6ad6
|
|
# sched_dumpstack: backtrace| 1: 0x400e6a99 0x400e4005 0x400e2754
|
|
# sched_dumpstack: backtrace| 2: 0x400f13ee 0x400e4005 0x400e2754
|
|
# ...
|
|
#
|
|
# Copy that to a file and call this script as:
|
|
# ./tools/btdecode.sh esp32 backtrace_file
|
|
#
|
|
# The result should be similar to the following:
|
|
# 0x400e1a2a: function_name at file.c:line
|
|
# 0x40082912: function_name at file.c:line
|
|
|
|
USAGE="USAGE: ${0} chip|toolchain-addr2line backtrace_file [elf_file]
|
|
If the first argument contains 'addr2line', it will be used as the toolchain's addr2line tool.
|
|
Otherwise, the script will try to identify the toolchain based on the chip name."
|
|
|
|
GREP=${GREP:-grep}
|
|
|
|
VALID_CHIPS=(
|
|
"esp32"
|
|
"esp32s2"
|
|
"esp32s3"
|
|
"esp32c3"
|
|
"esp32c6"
|
|
"esp32h2"
|
|
)
|
|
|
|
# Make sure we have the required argument(s)
|
|
|
|
if [ -z "$2" ]; then
|
|
echo "No backtrace supplied!"
|
|
echo "$USAGE"
|
|
exit 1
|
|
fi
|
|
|
|
elf_file="nuttx"
|
|
|
|
if [ -n "$3" ]; then
|
|
elf_file=$3
|
|
fi
|
|
|
|
# Check if the first argument is an addr2line tool or a chip
|
|
|
|
chip_or_tool=$1
|
|
if [[ $chip_or_tool == *addr2line* ]]; then
|
|
ADDR2LINE_TOOL=$chip_or_tool
|
|
else
|
|
chip=$chip_or_tool
|
|
if [[ ! " ${VALID_CHIPS[@]} " =~ " ${chip} " ]]; then
|
|
echo "Invalid chip specified! Valid options are: ${VALID_CHIPS[*]}"
|
|
echo "$USAGE"
|
|
exit 4
|
|
fi
|
|
|
|
# Set the appropriate addr2line tool based on the chip
|
|
case $chip in
|
|
esp32)
|
|
ADDR2LINE_TOOL="xtensa-esp32-elf-addr2line"
|
|
;;
|
|
esp32s2)
|
|
ADDR2LINE_TOOL="xtensa-esp32s2-elf-addr2line"
|
|
;;
|
|
esp32s3)
|
|
ADDR2LINE_TOOL="xtensa-esp32s3-elf-addr2line"
|
|
;;
|
|
esp32c3)
|
|
ADDR2LINE_TOOL="riscv-none-elf-addr2line"
|
|
;;
|
|
esp32c6)
|
|
ADDR2LINE_TOOL="riscv-none-elf-addr2line"
|
|
;;
|
|
esp32h2)
|
|
ADDR2LINE_TOOL="riscv-none-elf-addr2line"
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
# Make sure the elf file is accessible
|
|
|
|
if [ ! -f ${elf_file} ]; then
|
|
echo "NuttX binaries not found!"
|
|
exit 2
|
|
fi
|
|
|
|
# Check that the toolchain is in the PATH
|
|
|
|
if [ ! -x "$(command -v $ADDR2LINE_TOOL)" ]; then
|
|
echo "Toolchain for $chip_or_tool not found!"
|
|
exit 3
|
|
fi
|
|
|
|
# Decode backtrace
|
|
|
|
declare -A backtraces_before
|
|
declare -A backtraces_after
|
|
in_dump_tasks_section=false
|
|
|
|
while read -r line; do
|
|
if [[ $line =~ (\[CPU[0-9]+\]\ )?dump_tasks: ]]; then
|
|
in_dump_tasks_section=true
|
|
fi
|
|
|
|
if [[ $line =~ (\[CPU[0-9]+\]\ )?sched_dumpstack: ]]; then
|
|
task_id=$(echo $line | ${GREP} -oP 'backtrace\|\s*\K\d+')
|
|
addresses=$(echo $line | ${GREP} -oP '0x[0-9a-fA-F]+')
|
|
if $in_dump_tasks_section; then
|
|
if [[ -n "${backtraces_after[$task_id]}" ]]; then
|
|
backtraces_after[$task_id]="${backtraces_after[$task_id]} $addresses"
|
|
else
|
|
backtraces_after[$task_id]="$addresses"
|
|
fi
|
|
else
|
|
if [[ -n "${backtraces_before[$task_id]}" ]]; then
|
|
backtraces_before[$task_id]="${backtraces_before[$task_id]} $addresses"
|
|
else
|
|
backtraces_before[$task_id]="$addresses"
|
|
fi
|
|
fi
|
|
fi
|
|
done < "$2"
|
|
|
|
for task_id in "${!backtraces_before[@]}"; do
|
|
echo "Backtrace for task $task_id:"
|
|
for bt in ${backtraces_before[$task_id]}; do
|
|
$ADDR2LINE_TOOL -pfiaCs -e ${elf_file} $bt
|
|
done
|
|
echo ""
|
|
done
|
|
|
|
if $in_dump_tasks_section; then
|
|
echo "Backtrace dump for all tasks:"
|
|
echo ""
|
|
for task_id in "${!backtraces_after[@]}"; do
|
|
echo "Backtrace for task $task_id:"
|
|
for bt in ${backtraces_after[$task_id]}; do
|
|
$ADDR2LINE_TOOL -pfiaCs -e ${elf_file} $bt
|
|
done
|
|
echo ""
|
|
done
|
|
fi
|