ランタイムエラーが発生したときにCoretex-M4プロセッサから情報を取得する方法を学びます。
AUTHOR: Sebastian Wikström
Arduino UNO R4 WiFiは、ランタイムエラーが発生したときに、CmBacktraceを使い、Arm Core M4プロセッサからの有用な情報を、シリアル出力に表示します。出力にはaddr2line
コマンドを含み、エラーの発生元を見つけるために利用するスタックトレース(スタックバックトレースやスタックトレースバックとも呼ばれます)を生成するのに使われます。
このチュートリアルでは、この機能の使い方を示します。
必要なハードウェアとソフトウェア
ランタイムエラーを見る
シリアルモニタにランタイムエラー情報を取得するには、以下のステップに従ってください。
- スケッチで
Serial.begin()
を呼び出し、エラーが発生する前にシリアル接続が開始されていることを確認します。setup()
関数の最初に以下のコードを含めます。
|
|
-
UNO R4 WiFiボードをPCに接続します。
-
シリアルモニタを開きます。右上のシリアルモニタボタンをクリックするか、
メニューバーの、「ツール > シリアルモニタ」を選択します。
- スケッチを変更したら、書き込みボタンをクリックするか、
ボードのリセットボタンを押します。
- ボードで例外が発生すると、情報がシリアルモニタに表示されます。
-
「Register information」テーブルに従い、エラーの型が指定されます。型についての詳細は、ここ記載されています。
-
最終行は
addr2line
ユーティリティのコマンドが含まれています。addr2lineコマンドを実行するを参照してください。
スタックトレースを生成する
addr2line
ツールを使って、スタックトレースを生成することができます。以下の用例を見てください。
注意: addr2line
はWindows アプリケーションとしては利用できません。しかし、Windows Subsystem for Linux(WSL)上では動作します。
addr2line
ユーティリティは、Arduino UNO R4ボードパッケージに含まれています。しかし、この方法で動作させるには、出力に含まれるコマンドを修正する必要があります。便利なので、addr2line
をシステムにインストールしておくといいと思います。
addr2line
(オプション)をインストールするには、以下のOS別の手順に従ってください。
- Windows(WSL):
addr2line
は、Windowsアプリとしては動作しません。しかし、Windows Subsystem for Linux上で動作します。LinuxのUbuntuディストリビューションがデフォルトでインストールされ、そこにaddr2line
が含まれています。 - macOS:
addr2line
は、Homebrewを使い、ターミナルでbrew install binutils
を実行するとインストールできます。 - Linux:
addr2line
は、恐らくインストールされています。インストールされていなければ、apt-get install binutils
をターミナルで実行してください(Ubuntu、Debian)。他のディストリビューションでは、command-not-found.com/addr2lineを参照してください。
addr2line
コマンドをコピーする
Windows(WSL)
- シリアル出力からコマンドをコピーする
- テキストエディタにコマンドをペーストする
C:
を/mnt/c
に置き換え、全てのバックスラッシュ(\
)をスラッシュ(/
)に置き換える。
macOS
シリアル出力からコマンドをコピーする(修正不要です)。
Linux
シリアル出力からコマンドをコピーする(修正不要です)。
addr2line
コマンドを実行する
注意: スケッチは、addr2line
を実行するPCと同じPC上でコンパイルされている必要があります。
Windows(WSL)
- Windows Powershellを開く
- Windows Powershellで、
Ubuntu
トタイプし、エンターキーを押す - 修正したコマンドを、右クリックでWindows Powershellにペーストする
- コマンドを実行するためにエンターキーを押す
macOS
- ターミナルを開く
- ⌘ + Vを押し、コマンドをペーストする
- コマンドを実行するためにエンターキーを押す
Linux
- ターミナルを開く
- Ctrl + ⇧Shift + Vを押し、コマンドをペーストする
- コマンドを実行するためにエンターキーを押す
オプションで、-p
フラグをつければ、読みやすいフォーマットになります。
addr2line
の出力を読む
デフォルトで、コマンドは、各関数呼び出しに対して以下を出力します。
- アドレス: “
0x00004188
”,"0x0000426e
",…(これが不要なら-aフラグを削除してください) - 関数名: “
_ZN4UART5writeEh
”, “loop
”, … - 行番号:"
/Users/sebastianwikstrom/Documents/Arduino/ErrorInducer/ErrorInducer.ino:67
", …
以下の手順に従ってください。
- スケッチ内の出力の最上行を探してください。パスの後の数字が、エラーがおこった行番号です。例えば、
/Users/username/Documents/Arduino/ErrorInducer/ErrorInducer.ino:67
であれば、67行目でエラーが起こったことを示しています。出力を読み進めると、関数呼び出しが行われたステップをさかのぼることができます。
-
Arduino IDEでスケッチを開き、先ほどのステップでの行番号を探してください(番号は各行の左側に表示されています)
-
エラーが起こった行を解析し、なぜエラーが起こったのか理解するよう努めてください
- わからない場合は、Serial.println()関数で、使われている変数の値を出力してください。その後、スケッチを再度アップロードし、エラーが起こる前にそれらの変数がどのような状態であったかを、シリアル出力を使い、見てください。
- どこから関数が呼ばれたかを知るには、
addr2line
出力の、先行する関数を見てください。
この例では、while(true)
ループで何回かの繰り返し後、 numbers
配列の領域外へのアクセスが起こります。
追加の手順
addr2line
コマンドをコピーする(ボードパッケージ)
addr2line
コマンドをコピーするの手順を置き換えます。ボードパッケージのaddr2line
を直接使う場合は、以下の手順に従ってください。
Windows(WSL)
- シリアル出力からコマンドをコピーする
- テキストエディタにコマンドをペーストする
addr2line
を/mnt/c/Users/User/Appdata/Local/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-addr2line
に置き換える- -eフラグ以降のファイルパスについて、
C:
を/mnt/c
に置き換え、全てのバックスラッシュ(\
)をスラッシュ(/
)に置き換える。
macOS
- シリアル出力からコマンドをコピーする
- テキストエディタにコマンドをペーストする
addr2line
を/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-addr2line
に置き換える
Linux
- シリアル出力からコマンドをコピーする
- テキストエディタにコマンドをペーストする
addr2line
を.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-addr2line
に置き換える
オリジナルのページ
https://docs.arduino.cc/tutorials/uno-r4-wifi/stack-trace
最終更新日
November 13, 2023