2011-11-09 20 views
5

かなり大規模なSIPテレフォニーアプリケーションに取り組んでいます。時には、負荷の重い状態で統合Web UI(tntnetを使用して記述)を使用すると、プログラムがstd: :bad_allocがスローされます。何百ものスレッドが使用されています(アクティブな呼び出しにつき3つ)ので、例外を引き起こすコードの場所はかなりランダムですが、GUIを使用した後は常にあります。std :: bad_allocがスローされる他の考えられる理由

ここでは、メモリ不足のときにstd :: bad_allocがスローされる可能性があることを理解しています。この状況ではそうではありません。ヒープの破損があるときにスローされる可能性があると私は考えています。これは、コードベースに存在する可能性がある場所を探しています。

しかし、私の質問は、std :: bad_allocがメモリー不足やヒープ破損以外にスローされるような理由があるかどうかです。 LinuxでGNU g ++を使用しています。

+0

カスタムアロケータを使用していますか? – sehe

+0

私が知っているか、見たことはありません。 –

+0

bad_allocは、メモリの割り当てに失敗した場合にだけスローされますが、プログラムが未定義の処理を行う場合、未定義アクションの後にいつでもbad_allocをスローするなど –

答えて

5

おそらく、あなたは本当に記憶がありません。それは一貫して bad_allocだけがスローされる非常にまれなヒープ破損バグです。それは外科手術の精度で落書きするようなものです。

大量のメモリを割り当てるバグがコード内に存在する可能性があります。しかし、そのコードでは、少なくとも時間の大部分は、例外がスローされると予想されます。例外がいくつかの異なる場所から来ているという事実は、それに対して重いものです。

重度のフラグメンテーションは、特に実装が不良なプラットフォームでは、mallocの問題を引き起こす可能性があります。それはまれですが、それは起こります。

すぐにやりたいことの1つは、例外をキャッチし、/proc/self/mapsのコピーを保存する関数を呼び出すことです。これにより、プロセスのピーク時のメモリ使用量を知ることができます。プラットフォーム、ポリシー、またはハードウェアの限界に近い場所にいるかどうかを判断できます。

3

Linuxでは、現在のアドレス空間の制限を使用して、プロセスが使用できるメモリ量を人為的に制限することができます。 setrlimit(RLIMIT_AS, ...)でこれを手動で設定できます。これは、ulimit -vを使用して、bashrcのシェル全体に対して設定することもできます。これは、システム全体に対して/etc/security/limits.confに設定することもできます。この場所には/ proc/sysエントリがあるかもしれませんが、わかりません。

アドレス空間の上限に達すると、メモリをさらに割り当てようとすると、プロセスはstd :: bad_allocをスローします。 64ビットシステムでは、これは悪いアプリケーションやライブラリが利用可能なメモリを使い果たしず、システムをスワップまたは完全に動作させないようにする「安全」という点で優れたものです。プログラムがこれをどこかに設定していないことを確認し、残りの環境がそれを設定していないことを確認してください。プログラムのどこかにコードを挿入して、getrlimit(RLIMIT_AS, ...)と呼んで、どこかに忍び込まないようにすることができます。

実際にメモリが不足しているのを除いて、おそらくより一般的な原因は、メモリを割り当てるためにuin32_tまたはuint64_tが使用されていて、0から1を引いた符号付き整数ラップアラウンドケースです。非常に大きな要求割り当て(数千ペタバイトになる64ビット)になります。

いずれにしても、これを追跡する最良の方法はGDBです。アプリケーションが例外をまったく使用しないため(つまり、「catch」文がまったくない)、コアファイル(ulimit -c unlimited)を有効にすることができます。次にプログラムがクラッシュすると、OSはコアファイルを生成し、それをGDBにロードすると、プログラムがクラッシュした場所を示すバックトレースがすぐに得られます。

tryが使用され、この問題をデバッグしている間にコメントアウトする以外に、これらの不正なallocをキャッチしている場所がいくつかある場合は、GDBでアプリケーションを実行してcatch throwコマンドを使用できます例外がスローされるたびにGDBを中断させる。これらのいずれかを動作させるには、でコンパイルしないでください(-O3を使用している場合でも)-ggdbでコンパイルしてください。

関連する問題