Browse Source

Add helper script and workflow for analyzing crash logs included in Github comments

Petteri Aimonen 2 years ago
parent
commit
e9c89148a1
2 changed files with 109 additions and 0 deletions
  1. 54 0
      .github/workflows/analyze_crashlogs.yml
  2. 55 0
      utils/analyze_crashlog.sh

+ 54 - 0
.github/workflows/analyze_crashlogs.yml

@@ -0,0 +1,54 @@
+name: Analyze crash logs
+
+on:
+  issue_comment:
+    types: [created]
+  issues:
+    types: [opened, edited]
+
+jobs:
+  analyze_crashlog:
+    name: Analyze crash log
+    runs-on: ubuntu-20.04
+    if: |
+      (github.event_name == 'issue_comment' && (
+        contains(github.event.comment.body, 'CRASH') ||
+        contains(github.event.comment.body, 'WATCHDOG'))) ||
+      (github.event_name == 'issues' && (
+          contains(github.event.issue.body, 'CRASH') ||
+          contains(github.event.issue.body, 'WATCHDOG')))
+    permissions:
+      issues: write
+
+    steps:
+      - name: Check out code from GitHub
+        uses: actions/checkout@v3
+
+      - name: Install tools
+        run: |
+          sudo apt-get install binutils-arm-none-eabi
+
+      - name: Analyze crash log from issue body
+        if: github.event_name == 'issues'
+        env:
+          ISSUE_ID: ${{ github.event.issue.number }}
+          GH_TOKEN: ${{ github.token }}
+        run: |
+          gh api repos/${GITHUB_REPOSITORY}/issues/${ISSUE_ID}/comments --jq '.[-1].body' | grep Automatic && exit 0 # Comment only once
+          gh api repos/${GITHUB_REPOSITORY}/issues/${ISSUE_ID} --jq '.body' > comment.txt
+          echo -e 'Automatic analysis of the crash log:\n\n<pre>' > output.txt
+          utils/analyze_crashlog.sh comment.txt | tee -a output.txt
+          echo '</pre>' >> output.txt
+          grep '^0x' output.txt && gh issue comment ${ISSUE_ID} --body-file output.txt
+
+      - name: Analyze crash log from issue comment
+        if: github.event_name == 'issue_comment'
+        env:
+          ISSUE_ID: ${{ github.event.issue.number }}
+          GH_TOKEN: ${{ github.token }}
+        run: |
+          gh api repos/${GITHUB_REPOSITORY}/issues/${ISSUE_ID}/comments --jq '.[-1].body' > comment.txt
+          echo -e 'Automatic analysis of the crash log:\n\n<pre>' > output.txt
+          utils/analyze_crashlog.sh comment.txt | tee -a output.txt
+          echo '</pre>' >> output.txt
+          grep '^0x' output.txt && gh issue comment ${ISSUE_ID} --body-file output.txt

+ 55 - 0
utils/analyze_crashlog.sh

@@ -0,0 +1,55 @@
+#!/bin/bash
+
+# This script can be used for analyzing a crash report.
+# It tries to find a matching binary .elf either locally
+# or from github releases.
+#
+# Usage:
+#    utils/analyze_crashlog.sh                    # paste log to console, press ctrl-D to end
+#    utils/analyze_crashlog.sh zululog.txt        # read log from file
+#    utils/analyze_crashlog.sh zululog.txt path   # read log from file and find firmware at path
+
+if [ "x$1" = "x" ]; then
+    logfile=$(mktemp /tmp/crashlog-XXXXXXX)
+    cat - > $logfile
+else
+    logfile=$1
+fi
+
+repo="ZuluSCSI/ZuluSCSI-firmware"
+
+# Find firmware compilation time
+fwtime=$(grep 'FW Version' $logfile | tail -n 1 | egrep -o '[A-Z][a-z][a-z] [0-9]+ [0-9]+ [0-9:]+')
+
+# Check if the firmware file is available locally
+echo "Searching for firmware compiled at $fwtime"
+scriptdir=$( dirname -- "${BASH_SOURCE[0]}" )
+fwfile=$(find $scriptdir/.. $2 -name '*.elf' -exec grep -q "$fwtime" {} \; -print -quit)
+
+# Search Github for artifacts uploaded within few minutes of the compilation time
+if [ "x$fwfile" = "x" ]; then
+    echo "Searching on Github"
+    enddate=$(date "+%Y-%m-%dT%H:%M" -d "$fwtime 180 seconds")
+    runid=$(gh api repos/$repo/actions/artifacts \
+        --jq ".artifacts[] | select(.created_at <= \"$enddate\") | .workflow_run.id" | head -n 1)
+    if [ "x$runid" != "x" ]; then
+        tmpdir=$(mktemp -d /tmp/crashlog-XXXXXXX)
+        echo "Workflow run: https://github.com/$repo/actions/runs/$runid"
+        echo "Downloading artifact to $tmpdir (if permission denied, use 'gh auth' to login)"
+        (cd $tmpdir; gh run download -R $repo $runid)
+        fwfile=$(find $tmpdir -name '*.elf' -exec grep -q "$fwtime" {} \; -print -quit)
+    fi
+fi
+
+if [ "x$fwfile" = "x" ]; then
+    echo "Did not find firmware built at $fwtime!"
+    exit 1
+else
+    echo "Found firmware at $fwfile"
+fi
+
+# Get crash addresses
+echo
+for addr in $(egrep -o '[ x][0-9a-fA-Z]{8}' $logfile | tr -d 'x'); do
+    arm-none-eabi-addr2line -Cafsip -e "$fwfile" $addr | grep -v ?
+done