Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions packages/bsp/common/usr/bin/armbian-debug
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#!/bin/bash
#
# Copyright (c) Authors: https://www.armbian.com/authors
#
# Collect and upload system debug information for Armbian support.
#
############################################################################

# Config:
declare -a paste_servers=("paste.armbian.com" "paste.next.armbian.com" "paste.armbian.de" "paste.armbian.eu")
if [[ "${PASTE_SERVER_HOST}" != "" ]]; then
echo "Using custom paste server: '${PASTE_SERVER_HOST}'"
paste_servers=("${PASTE_SERVER_HOST}" "${paste_servers[@]}")
fi

# Set up colors if available
if test -t 1; then
ncolors=$(tput colors)
if test -n "$ncolors" && test $ncolors -ge 8; then
BOLD="$(tput bold)"
NC='\033[0m' # No Color
fi
fi

Main() {
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Check if curl is available, install if not
if ! command -v curl > /dev/null 2>&1; then
echo "curl not found in PATH. Trying to install it..." >&2
if [ "$(id -u)" = "0" ]; then
apt-get -f -y install curl
else
echo "Please install curl: sudo apt-get install curl" >&2
exit 1
fi
fi

# 5 second countdown with option to force stdout output
force_stdout=false
echo -e "\n${BOLD}Collecting debug information for Armbian support${NC}"
echo -e "Press any key within 5 seconds to output to stdout instead of uploading..."
for i in {5..1}; do
echo -ne "\r$i seconds remaining... "
# Read with timeout (works in bash)
if read -s -n 1 -t 1; then
force_stdout=true
echo -e "\n${BOLD}Key pressed - will output to stdout${NC}\n"
break
fi
done
if [ "$force_stdout" = false ]; then
echo -e "\rStarting upload... "
fi

# Collect and process the info
if [ "$force_stdout" = true ]; then
# Output to stdout with line numbers
CollectSupportInfo |
sed -E 's/([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3})/XXX.XXX.\3\4/g' |
awk '!NF{$0=" "}1' | nl -
echo -e "\nPlease upload the ${BOLD}whole output${NC} above to an online pasteboard service\nand provide the URL at the place where you have been asked for this.\n"
else
# Try to upload to paste servers
upload_success=false

for paste_server in "${paste_servers[@]}"; do
echo "Collecting info and sending to ${paste_server}..."
declare -i counter=0
{
LC_ALL=C date
echo "-----------------------------------------------------------------------------------------------------------------------------"
dmesg --color=always
echo "-----------------------------------------------------------------------------------------------------------------------------"
CollectSupportInfo || echo "Error collecting support info"
} |
sed -E 's/([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3})/XXX.XXX.\3\4/g' |
curl -s --fail --connect-timeout 10 --max-time 30 --data-binary @- "https://${paste_server}/log"

# Save PIPESTATUS before any other command
pipe_status=("${PIPESTATUS[@]}")

# Check PIPESTATUS
for i in "${pipe_status[@]}"; do
counter=$((counter + 1))
if [[ $i -ne 0 ]]; then
echo "Failed (pipe ${counter} returned ${i})."
continue 2
fi
done

# If we get here, upload succeeded
upload_success=true
break
done

if [ "$upload_success" = true ]; then
echo -e "\n${BOLD}Upload successful!${NC} Please post the URL at the place where you have been asked for.\n"
else
echo -e "\n${BOLD}All upload attempts failed. Outputting to stdout instead:${NC}\n"
CollectSupportInfo |
sed -E 's/([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3})/XXX.XXX.\3\4/g' |
awk '!NF{$0=" "}1' | nl -
echo -e "\nPlease upload the ${BOLD}whole output${NC} above to an online pasteboard service\nand provide the URL in the forum where you have been asked for this.\n"
fi
fi
Comment on lines +56 to +106
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Inconsistent data between upload path and stdout/fallback paths.

The upload path (lines 70-76) sends date + dmesg --color=always + CollectSupportInfo, but:

  • The direct stdout path (lines 59-61) only sends CollectSupportInfo (no date, no dmesg).
  • The fallback stdout path (lines 101-103) also only sends CollectSupportInfo.

This means support staff will get different diagnostic data depending on which path was taken, and dmesg output — arguably the most useful debug artifact — is missing from both stdout paths.

Additionally, on upload failure the fallback re-runs CollectSupportInfo (line 101), meaning the data shown to the user may differ from what was attempted for upload (system state drift, extra delay).

Consider extracting the full collection (date + dmesg + CollectSupportInfo) into a temp file once and reusing it for both upload and stdout paths.

Sketch of a possible approach
+	# Collect all data once into a temp file
+	tmpfile=$(mktemp /tmp/armbian-debug.XXXXXX)
+	trap "rm -f '$tmpfile'" EXIT
+	{
+		LC_ALL=C date
+		echo "-----------------------------------------------------------------------------------------------------------------------------"
+		dmesg
+		echo "-----------------------------------------------------------------------------------------------------------------------------"
+		CollectSupportInfo || echo "Error collecting support info"
+	} > "$tmpfile"
+
 	if [ "$force_stdout" = true ]; then
-		CollectSupportInfo |
-			sed -E 's/...' |
+		sed -E 's/([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3})/XXX.XXX.\3\4/g' < "$tmpfile" |
 			awk '!NF{$0=" "}1' | nl -
 	else
 		for paste_server in "${paste_servers[@]}"; do
-			{
-				LC_ALL=C date
-				...
-				CollectSupportInfo || echo "Error collecting support info"
-			} |
-				sed ... |
-				curl ...
+			sed -E 's/([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3})/XXX.XXX.\3\4/g' < "$tmpfile" |
+				curl -s --fail --connect-timeout 10 --max-time 30 --data-binary `@-` "https://${paste_server}/log"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bsp/common/usr/bin/armbian-debug` around lines 56 - 106, The upload
path and both stdout/fallback paths collect different info and re-run
CollectSupportInfo which can produce inconsistent results; change the flow to
collect the full payload once into a temp file (capture LC_ALL=C date, dmesg
--color=always, and CollectSupportInfo into a temp file), then use that temp
file for the curl upload loop (while still applying the IP-scrubbing sed) and
for any stdout/fallback printing (apply awk/nl same as current). Update logic
around paste_servers, upload_success, and PIPESTATUS to read from the temp file
instead of re-invoking CollectSupportInfo, and ensure the temp file is cleaned
up at the end.

}

CollectSupportInfo() {
[[ -s /var/log/armbian-hardware-monitor.log ]] && cat /var/log/armbian-hardware-monitor.log || zcat /var/log/armbian-hardware-monitor.log.1.gz 2> /dev/null
[[ -f /boot/armbianEnv.txt ]] && LOGLEVEL=$(awk -F'=' '/^verbosity/ {print $2}' /boot/armbianEnv.txt)
LOGLEVEL=${LOGLEVEL:-1}
if [ "$LOGLEVEL" -gt 4 ]; then
VERBOSE='-v'
which lshw > /dev/null 2>&1 && (
echo -e "\n### lshw:"
lshw -quiet -sanitize -numeric
)
fi
lsusb > /dev/null 2>&1 && (
echo -e "\n### lsusb:\n"
lsusb ${VERBOSE} 2> /dev/null
echo ""
lsusb -t 2> /dev/null
)
lspci > /dev/null 2>&1 && (
echo -e "\n### lspci:\n"
lspci ${VERBOSE} 2> /dev/null
)
nvme > /dev/null 2>&1 && (
echo -e "\n### nvme:\n"
nvme list 2> /dev/null
)
[ -z "$SUDO_USER" ] || echo -e "\n### Group membership of $(groups "$SUDO_USER")"
echo -en "\n### Userland"
[[ -f /etc/armbian-release ]] && echo -en " generated with Armbian Build Framework"
echo -en ":\n"
echo -e "\n$(grep PRETTY_NAME /etc/os-release)"
echo -e "\n### Installed packages:\n\n$(dpkg -l | grep -E "openmediavault|armbian| linux-")"
echo -e "\n### Loaded modules:\n\n$(lsmod)"
[[ -f /var/log/nand-sata-install.log ]] && echo -e "\n### nand-sata-install.log:\n\n$(cat /var/log/nand-sata-install.log)"
echo -e "\n### Current sysinfo:\n\n$(command -v iostat >/dev/null 2>&1 && iostat -p ALL | grep -v "^loop")\n\n$(vmstat -w)\n\n$(free -h)\n\n$(zramctl 2> /dev/null)\n\n$(uptime)\n\n$(dmesg | tail -n 250)"
echo -e "\n"
if [[ "$(id -u)" -eq "0" ]]; then
for sysfsnode in /proc/sys/vm/*; do
sysctl "${sysfsnode/\/proc\/sys\/vm\//vm.}"
done
fi
echo -e "\n### interrupts:\n$(cat /proc/interrupts)"
ls /tmp/armbianmonitor_checks_* > /dev/null 2>&1 || return 0
for file in /tmp/armbianmonitor_checks_*; do
echo -e "\n### \c"
ls "${file}" | cut -f1 -d.
echo
cat "${file}"
done
} # CollectSupportInfo

Main "$@"
Loading