1

IAR EWARM IDEとコンパイラを使用して、Cortex-M3組み込みマイクロコントローラ(Atmel SAM3S)用のソフトウェアを開発しています。何らかの理由で、バッファオーバーフロー、またはメモリリークが発生し、スタックが破損していると思われます。これは、突然、コードスペースの外でスタックしていることに気付いたためです。

私がこの質問をする理由は、この混乱の実際の原因を見つけるのが非常に難しいためです。問題の原因を突き止めたいときに、どの手法を使用しているかを知りたいのです。

メモリデバッガ、インサーキットトレースデバッグハードウェアなどを使用していますか。

4

4 に答える 4

4

カナリア値を使用してみてください。これが基本的な方法です-いくつかあるとしましょうstruct

struct foo {
    unsigned long bar;
    void * baz;
};

次のように変更します。

struct foo {
    unsigned long canary1;
    unsigned long bar;
    void * baz;
    unsigned long canary2;
};

を初期化するときstruct、いくつかの任意の値をcanary1およびに入れますcanary2。で何らかの操作を行うときはいつでもstruct、値が同じままかどうかを確認してください。これにより、バッファ オーバーフローやスタック スマッシングが発生した場合に、それを検出できます。自動変数を使用して同じ内部関数を実行できます。

int foo(int bar) {
      unsigned long canary1 = 0xDEADBABE;
      char baz[20];
      unsigned long canary2 = 0xBAD0C0DE;
      ...
}

等々。する前に、値が同じままであることを確認することを忘れないでくださいreturn。また、コードを一貫して同じ場所にジャンプできる場合は、そこにコード (またはブレークポイント) を配置して、スタック トレースを取得してみてください。

GCC はこれらのカナリア値を単独で追加する方法を知っていますが、コンパイラがそれを実行できるかどうかはわかりません。ただし、手動で行うこともできます。

于 2012-06-18T12:13:08.663 に答える
2

プログラムカウンタはレジスタなので「上書き」できません。あなたが言うように、スタックが上書きされ、スタックから無効な戻りアドレスを読み取るリターン命令を実行すると、ララランドにジャンプする可能性があります。

私のお気に入りのデバッグ方法は出力することですが、もちろん組み込みターゲットでは難しいかもしれません。2 番目に良い方法は、疑わしいルーチンをステップ実行することです。

また、割り込みサービス ルーチンなど、ジャンプを引き起こすことが知られているものも調査する必要があります。

于 2012-06-18T11:52:27.917 に答える
2

STM32 で IAR EWARM を使用すると、同様の問題が発生しました。メモリ ダンプ、逆アセンブル、カナリア、すべて何も見つかりませんでした。最後に、以前のバージョンの EWARM にロールバックすると、問題は解消されました。IAR サポートにメッセージを送信しましたが、返信がありません。申し訳ありませんが、これがどのバージョンの EWARM だったか覚えていません。数年前のプロジェクトです。

メモリ ウィンドウを開いたままにして、最初にカナリア テストを試します。それでもランダムにコード空間から飛び出す場合は、古いバージョンの EWARM をインストールしてみてください。

于 2012-06-18T14:41:39.820 に答える
1

追加できることの 1 つは、ARM チップでは、BX または BLX の代わりに BL がどこかにあり、チップが間違った Thumb/ARM モードになる可能性があるということです。後のチップほど一般的ではありませんが、それでも...

どこにもジャンプしていない場合は、関数ポインタ テーブルの不良、割り込みベクトル テーブルの上書き、そして最も簡単にテストできるスタック オーバーフローを探します。既知のバイト値をスタック領域にドロップし、クラッシュが発生したときに、デバッガーで残っているスタックの量を確認します。ない場合は、そこに行きます。

また、問題を特定するために、過去 X 日間に何が変更されたかを標準的に確認します。最後に、コード全体を印刷して、悪いジャンプが発生している場所を絞り込んでください。1 つまたは 2 つの関数に絞り込むことができれば、アセンブラーをトレースして、それがコンパイラーの問題なのか、メモリの問題なのか、割り込みの問題なのかをすぐに確認できます。幸運を!

于 2012-06-18T14:57:57.113 に答える