IDE: MCUXpresso IDE 25.6
デバッガ: GNU Arm GDB 15.2.90.20241130-git
ツールチェーン: GNU Arm ツールチェーン 14.2.Rel1
ターゲット: NXP LPC845、Arm Cortex-M0+
デバッグプローブ: LinkServer を使用したオンボード LPC-Link2
ホスト: Windows
SysTickからThreadモードコードへの合成例外スタックフレームを用いるCortex-M0+アプリケーションをデバッグすると、GDBは応答しなくなります。
ファームウェアは、以下の方法で例外戻りを実行します。
bx lrLR = 0xFFFFFFF9 (MSPを使ったThreadモードに戻る)。
合成例外フレームには、有効なサムモード宛先PCとxPSRが含まれています。アプリケーションは物理的ターゲット上で動作しますが、GDBは宛先関数で停止すると応答しなくなります。
症状には以下が含まれます。
可変ホバー検査が機能しなくなりました。
メモリビューには????????が表示されます。
GDBコマンドやインフォThreadは応答しなくなります。
デバッグセッションは通常、終了とクリーンアップが必要です。
例外戻り値をまたいで命令ステップ実行するのではなく、宛先にハードウェアブレークポイントを設定した場合にも、同様の問題が発生します。
アプリケーションを通常通りデバッグし始めてください。
bx lr例外復帰命令の直前で停止してください。
目的関数System()に別のブレークポイントを設定します。
例外処理をスキップして戻るか、目的のブレークポイントまで続行します。
GDBは宛先に到達するが、その後応答しなくなる。
この不具合は、通常のGDB構成でも再現可能です。
リモートプロトコルトレースを有効にするには:
set logging file gdb-remote.log
set logging overwrite on
set logging enabled on
set debug remote 1GDBは、リモートメモリの読み取りにおいて、同じシーケンスを繰り返し実行していることが明らかになった。
m1b4,4 -> 91010000
m1ba,4 -> 00000000
m1bc,4 -> 00000001
m1c0,4 -> f9ffffff
m190,4 -> 07490868このシーケンスは無限に繰り返される。
LinkServerはリクエストを認識し、正常に応答します。したがって、このトレースは通常の通信タイムアウトを示すものではありません。
特に、 0x1c0の応答には例外戻り値である0xFFFFFFF9が含まれている。
GDBに以下のコマンドを入力します。
set backtrace limit 1繰り返しテストで観察された不具合を防止する。
この設定を有効にすると:
デバッガーが同じ例外戻り値の境界を繰り返し越えています。
どちらのブレークポイントも正常に機能します。
可変ホバー検査は目的地で機能します。
デバッグセッションは応答性を維持しています。
この回避策は、以下の方法で構成された GDB コマンド ファイルに配置した場合にも機能します。
デバッグ構成 → GDBデバッガー → GDBコマンドファイル
アプリケーションやアセンブリの改造は不要です。
同じターゲット、デバッグプローブ、IDEが従来のファームウェアを正常にデバッグします。
合成例外戻り値のシムを使用せずに宛先関数を呼び出す場合も機能します。
従来のSysTickハンドラでは、このような不具合は発生しません。
この問題は、合成例外リターン後の実行状態を処理するGDBに特に関連付けられているようです。
GDBは例外発生後も応答性を維持し、ステップ実行、レジスタ検査、メモリ検査、変数評価を可能にするべきである。
もしGDBが生成されたスタックフレームを解釈できない場合は、エラーを報告するかアンワインドを終了すべきであり、無期限に繰り返されるメモリ-読み込みシーケンスに入るべきではありません。
セットバックトレース限界1の有効性は、GDBのARM Cortex-Mスタックフレームアンワインドやフレーム解析が関与していることを強く示唆しています。
正確な内部原因は特定されていない。
GDBのARM Cortex-M例外フレーム処理と合成例外リターンの相互作用を調査してください。
特に、なぜデバッガが同じターゲットメモリ位置を繰り返し読み込むのか、フレームアンワインドが無限ループに入る可能性があるかどうかを明らかにします。
この回避策はデバッグ機能を復元しますが、バックトレースの深度を制限するため、有効な例外戻りシーケンスには必要ないはずです。