2

Micrium の uC/OS-III RTOS を使用しています。RTOS で malloc の戻り値を取得しようとしています。RTOS が開始される前に 99999 の malloc を実行すると (RAM に対して多すぎる)、null ポインターが返されます。これは想定どおりです。

RTOS の開始時およびタスク内でこれと同じ malloc を実行すると、予期しない null ポインターが返されません。ただし、この時点でシステムはフリーズします。

誰もこれについて説明がありますか?

前もって感謝します

編集:

情報については、ルネサスの RX62N マイクロコントローラーと GNURX コンパイラーを使用しています。

プログラムは実際にはフリーズしません。プログラムは、(NULL ポインターではなく) 有用なポインターを取得したと「考え」、実行を続けます。ある時点で、プログラムはそのプログラム カウンターを 00000000 に変更して停止します。そのため、例外に入らないため、キャッチできません。

ただし、RTOS が起動する前にmallocが呼び出される場合と、RTOS が起動される場合とでは、何かが異なります。違いは、 mallocの非常に深いアセンブリ コードにあります。

ある時点で、次の命令が実行されます

CMP         R1,R7
BGTU.B      0FFF802C0H
ADD         R14,R7

あまりにも多くの RAM を割り当てようとしている場合、BGTU.B命令は分岐せず、プログラムはADD命令を続行します。これは、RTOS を開始する前にmallocを実行すると完全に機能し、後で実行すると失敗します。

These are the values I get in several cases

Outside RTOS (allocable number: 10)
R1: 00008348
R7: 00000014

Outside RTOS (not allocable number: 9999)
R1: 00008348
R7: 00002718

Inside RTOS (allocable number: 10)
R1: FFFFF9D0
R7: 00000014

Inside RTOS (not allocable number: 9999)
R1: FFFFF9D0
R7: 00002718

全体の状況が明確であることを願っています。できる限り説明しようとしました:P

前もって感謝します

4

2 に答える 2

0

図の 2 番目のケースを除いて、R7 には割り当てのサイズ (要求されたサイズ + アライメント + ヒープ管理データ) が含まれているように見えます。直観的に R7=0x2718 は 999 バイトの割り当てに対応するため、これはタイプミスであると思われます。

R1には、メモリが割り当てられるヒープブロックのサイズが含まれていると思います。これは、CMPが理にかなっているからです。ブロックが十分に大きくない場合、失敗します。

ただし、RTOS が実行されている場合、R1 の値は非常に大きくなり、明らかに正しくありません。これは、ヒープが破損した場合に発生する可能性があります。これは、ヒープに割り当てられたバッファーをオーバーランした場合に発生します。ヒープからスレッド スタックを割り当てていて、スタックが小さすぎる場合は、同じ効果があります。スレッド スタックは、最悪の場合のコール スタックに加えて、コンテキスト スイッチをサポートするために RTOS で必要とされるものに十分な大きさである必要があります。ヒープからスタックを割り当てていない場合でも、スレッド スタックがヒープ メモリに隣接している場合、スタック オーバーフローが同じ影響を与える可能性があります。

ヒープが破損するもう 1 つの方法は、相互排除またはクリティカル セクションを強制せずに、複数のスレッドで割り当てまたは割り当て解除を同時に実行することです。RTOS と統合するために必要な変更を行っていない限り、標準ライブラリのヒープ管理がスレッドセーフである可能性は低いです。これは、RTOS と標準ライブラリが同じベンダーから提供されている場合 (たとえば、両方が提供されている場合) に当てはまる可能性があります。コンパイラで)。

于 2012-05-21T16:16:53.210 に答える