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
でコンパイルしてください。
カスタムアロケータを使用していますか? – sehe
私が知っているか、見たことはありません。 –
bad_allocは、メモリの割り当てに失敗した場合にだけスローされますが、プログラムが未定義の処理を行う場合、未定義アクションの後にいつでもbad_allocをスローするなど –