私の C アプリケーションは、独自のメモリ管理を行う 3rd ライブラリを使用しています。堅牢にするために、私のアプリケーションには、空きメモリ不足によるライブラリ関数の失敗に対処するコードがあります。
このコードをテストしたいと思います。そのためには、メモリ不足による障害をシミュレートする必要があります。
これにはどのツールが推奨されますか? 私の環境は Linux/gcc です。
私の C アプリケーションは、独自のメモリ管理を行う 3rd ライブラリを使用しています。堅牢にするために、私のアプリケーションには、空きメモリ不足によるライブラリ関数の失敗に対処するコードがあります。
このコードをテストしたいと思います。そのためには、メモリ不足による障害をシミュレートする必要があります。
これにはどのツールが推奨されますか? 私の環境は Linux/gcc です。
ulimit
メモリなど、ユーザーが使用できるリソースの量を制限するために使用できます。したがって、テスト ユーザーを作成し、そのメモリ使用量をプログラムを起動するのに十分な量に制限し、プログラムが停止するのを観察します :)
例:
ulimit -m 64
64kb のメモリ制限を設定します。
有効なポインターの代わりに null をランダムに返す独自の malloc ラッパーを作成します。まあ、またはユニットテストをしたい場合は、一貫して失敗します。
メモリをオーバーコミットするオペレーティング システム (Linux や Windows など) では、メモリ不足エラーを処理することはできません。malloc は有効なポインターを返す場合があり、後で逆参照しようとすると、オペレーティング システムがメモリ不足と判断し、プロセスを強制終了する場合があります。
http://www.reddit.com/comments/60vys/how_not_to_write_a_shared_library/は、これに関する優れた記事です。
サードパーティ ライブラリの代わりに、同じインターフェイスを使用して独自のモック ライブラリを作成できます。LD_PRELOAD を使用して、サードパーティ ライブラリの選択した関数をオーバーライドすることもできます。
Linux (おそらく POSIX) 固有のバージョンを提供できます: __malloc_hook、__realloc_hook、__free_hook。これらは malloc.h で宣言されています。
編集: 少し詳しく: これらは関数ポインターです (正確な宣言については、malloc.h とそのマンページを参照してください)。したがって、移植性が問題になる場合は、これを使用しないでください。
プラットフォームに依存しない解決策は、malloc マクロを宣言することです。テストしている場合、これはフックと実際の malloc を呼び出します。
memhook.h:
#define malloc(s) (my_malloc(s))
memhook.c:
#include "memhook.h"
#undef malloc
#include <stdlib.h>
等
これを使用して、リークを検出したり、割り当てをランダムに失敗させたりすることができます。
さらに、Valgrindを使用してすべてをテストし、プログラムのメモリ動作に関する有用なレポートを取得する必要があります。
Berkeley/Stanford ROC groupなど、リカバリ指向のコンピューティング サイトを調べてみるとよいでしょう。これらの人々の何人かが以前に話しているのを聞いたことがありますが、彼らはコードを使用して C ランタイムにランダムにエラーを挿入しています。ページの下部に FIT ツールへのリンクがあります。
(以前の回答の一部を補完するものとして)
実行可能ファイルで使用できる malloc インターセプト ライブラリの例については、「Electric Fence」を参照してください (たとえば、LD_PRELOAD トリックを使用)。
malloc を傍受したら、失敗を引き起こしたいものを何でも使用できます。ランダムにトリガーされる障害は、システムのさまざまな部分に対する適切なストレス テストになります。要求されたメモリの量に基づいて、失敗の確率を変更することもできます。
ちなみに、あなたのアイデアは興味深いアイデアです。明らかに、私のコードの一部でやりたいことです...
bash で ulimit コマンドが必要です。試す
ulimit を助けるbash シェル プロンプトで。
sqlite3 がこれを行う方法を見てください。メモリ不足のテストを含む広範な単体テストを実行します。
malloc のページ、特にSection 4.0も参照してください。