Skip to content

Commit c34904d

Browse files
committed
New article: "Debug runtime errors on UNO R4 WiFi using stack trace"
1 parent 424a523 commit c34904d

File tree

6 files changed

+117
-0
lines changed

6 files changed

+117
-0
lines changed
142 KB
Loading
133 KB
Loading
29.9 KB
Loading
448 Bytes
Loading
1.81 KB
Loading
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
---
2+
title: Debug runtime errors on UNO R4 WiFi using stack trace
3+
---
4+
5+
The UNO R4 WiFi uses [CmBacktrace](https://github.com/armink/CmBacktrace) to print useful information from the **Arm Cortex-M4** processor as serial output when a runtime error occurs. The output includes an `addr2line` command that can used to produce a **stack trace** (also **stack backtrace**, or **stack traceback**), which can be used to find the source of the error.
6+
7+
---
8+
9+
## Get runtime error information in the Serial Monitor
10+
11+
Follow these steps:
12+
13+
1. Ensure that a serial connection must be initiated before the error occurs, by calling [Serial.begin()](https://www.arduino.cc/reference/en/language/functions/communication/serial/begin/) in your sketch. You can include this code inside the beginning of the `setup()` function:
14+
15+
```
16+
Serial.begin(115200);
17+
while (!Serial);
18+
```
19+
20+
2. Connect your UNO R4 WiFi board to your computer.
21+
3. Open the Serial Monitor. Click the ![Serial Monitor icon](assets/symbol_monitor.png) **Serial Monitor** button in the top-right corner or select **Tools > Serial Monitor** in the menu bar.
22+
4. If you made any changes to your sketch, click the ![Upload icon](assets/symbol_upload2.png) **Upload** button. Otherwise, you can simply press the **RESET** button on the board.
23+
5. If an exception occurs on the board, information will be displayed in the Serial Monitor.
24+
25+
![Serial output.](assets/addr2line-example-serial.png)
26+
27+
6. Following the "Registers information" table, the type of fault will be specified. You can read more about the types [here](https://wiki.segger.com/Cortex-M_Fault#Cortex-M_Fault_Exceptions).
28+
7. The last line includes a command for the `addr2line` utility. See [Running addr2line for more information](#running-addr2line).
29+
30+
---
31+
32+
<a id="running-addr2line"></a>
33+
34+
## Use addr2line to generate a stack trace
35+
36+
> **Note:** `addr2line` is not available as a native Windows application, but can be run with [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/install).
37+
38+
The `addr2line` utility is included in the **Arduino UNO R4 Boards** boards package. However, running it in this way requires modifying the command included in the output. For convenience, you may want to install `addr2line` on your system.
39+
40+
Install `addr2line` (optional):
41+
42+
* **Windows (WSL):** `addr2line` is not available as a native Windows application, but can be run with [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/install). The Ubuntu distribution of Linux is installed by default and should come with `addr2line`.
43+
* **macOS:** `addr2line` can be installed with [Homebrew](https://brew.sh/) by running `brew install binutils` in Terminal.
44+
* **Linux:** `addr2line` may already be installed on your system. Otherwise, run `apt-get install binutils` in Terminal (Ubuntu, Debian), or see [command-not-found.com/addr2line](https://command-not-found.com/addr2line) for other distributions.
45+
46+
### 1. Copy the addr2line command (and modify it if necessary)
47+
48+
**If addr2line is installed on your system:**
49+
50+
* **Windows (WSL):**
51+
1. Copy the command from the serial output.
52+
2. Paste the command into a text editor.
53+
3. Replace `C:` with `/mnt/c` and replace all backslashes (`\`) with forward slashes (`/`).
54+
* **macOS:** Copy the command from the serial output (no modification required).
55+
* **Linux:** Copy the command from the serial output (no modification required).
56+
57+
**Using the addr2line from the board package:**
58+
59+
* **Windows (WSL):**
60+
1. Copy the command from the serial output.
61+
2. Paste the command into a text editor.
62+
3. Replace the word `addr2line` with `/mnt/c/Users/User/Appdata/Local/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-addr2line`
63+
4. For the file path after the `-e` flag, replace `C:` with `/mnt/c` and replace all backslashes (`\`) with forward slashes (`/`).
64+
65+
* **macOS:**
66+
1. Copy the command from the serial output.
67+
2. Paste the command into a text editor.
68+
3. Replace the word `addr2line` with `~/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-addr2line`.
69+
* **Linux:**
70+
1. Copy the command from the serial output.
71+
2. Paste the command into a text editor.
72+
3. Replace the word `addr2line` with `.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-addr2line`.
73+
74+
### 2. Running the addr2line command
75+
76+
> **Note:** The sketch needs to have been compiled on the same computer you are running `addr2line` on.
77+
78+
* **Windows (WSL):**
79+
1. Open [Windows Powershell](https://learn.microsoft.com/en-us/powershell/scripting/windows-powershell/starting-windows-powershell?view=powershell-7.3).
80+
2. Type `Ubuntu` into Windows Powershell and press <kbd>Enter</kbd>.
81+
3. Paste the modified command into Windows Powershell by right-clicking on the window.
82+
4. Press <kbd>Enter</kbd> to run the command.
83+
* **macOS:**
84+
1. Open Terminal.
85+
2. Press <kbd>⌘</kbd> + <kbd>V</kbd> to paste the command.
86+
3. Press <kbd>Enter</kbd> to run the command.
87+
* **Linux:**
88+
1. Open Terminal.
89+
2. Press <kbd>Ctrl</kbd> + <kbd>⇧Shift</kbd> + <kbd>V</kbd> to paste the command.
90+
3. Press <kbd>Enter</kbd> to run the command.
91+
92+
Optionally, you can add the `-p` flag to your command for a more readable format.
93+
94+
### 3. Reading the addr2line output
95+
96+
By default, the command outputs the following for each function call:
97+
98+
* **address:** "`0x00004188`", "`0x0000426e`", ... (remove the `-a` flag if you don't want to include these)
99+
* **function name:** "`_ZN4UART5writeEh`", "`loop`", ...
100+
* **line number** "`/Users/sebastianwikstrom/Documents/Arduino/ErrorInducer/ErrorInducer.ino:67`, ...
101+
102+
Follow these steps:
103+
104+
1. Look for the topmost line in the output that's inside your sketch. The number following the path is the line number where the error occurred. For example, `/Users/username/Documents/Arduino/ErrorInducer/ErrorInducer.ino:67` indicates that the error occurred on line 67. By reading further down the output, you can step backward through the function calls that were made.
105+
106+
![Reading the addr2line stack trace in Terminal.](assets/addr2line-terminal.png)
107+
108+
2. Open the sketch in Arduino IDE and find the line number from the previous step (the number is displayed to the left of each line).
109+
3. Analyze the row where the error occurred and try to understand what may be triggering the error.
110+
111+
* If you're not sure, use the [Serial.println()](https://www.arduino.cc/reference/en/language/functions/communication/serial/println/) function to output the values of any variables being used. Then upload the sketch again, and use the serial output to see what the states of those variables were before the error occurred.
112+
113+
* To see from where the function was called, look at the preceding function call in the `addr2line` output.
114+
115+
In this example, an out-of-bounds access of the `numbers` array occurs after a few iterations of the `while(true)` loop:
116+
117+
![Analyzing the code.](assets/addr2line-example.png)

0 commit comments

Comments
 (0)