メモリ リークの問題を検出するために、DevPartners boundchecker を使用しています。次のような文字列オーバーフローは見つかりませんが、素晴らしい仕事をしています
char szTest [1] = "";
for (i = 0; i < 100; i ++) {
strcat (szTest, "hi");
}
質問-1: BoundsChecker にこれを検出させる方法はありますか?
質問 2: そのような問題を検出できる他のツールはありますか?
メモリ リークの問題を検出するために、DevPartners boundchecker を使用しています。次のような文字列オーバーフローは見つかりませんが、素晴らしい仕事をしています
char szTest [1] = "";
for (i = 0; i < 100; i ++) {
strcat (szTest, "hi");
}
質問-1: BoundsChecker にこれを検出させる方法はありますか?
質問 2: そのような問題を検出できる他のツールはありますか?
devpartner (msvc6.6) (devpartner 7.2.0.372) で試してみました
あなたの観察された行動を確認します。ループの約 63 回のパスの後、アクセス違反が発生します。
この問題について、コンピュウェアは何と言っていますか?
CppCheckはこの問題を検出します。
1 つのオプションは、宛先バッファーに関する情報を持たない文字列関数の使用を単純に禁止することです。次のような一連のマクロを、一般的に含まれるヘッダーに含めると役立ちます。
#define strcpy strcpy_is_banned_use_strlcpy
#define strcat strcat_is_banned_use_strlcat
#define strncpy strncpy_is_banned_use_strlcpy
#define strncat strncat_is_banned_use_strlcat
#define sprintf sprintf_is_banned_use_snprintf
そのため、「禁止された」ルーチンを使用しようとすると、リンカ エラーが発生し、代わりに何を使用すべきかが示されます。MSVC は、_CRT_SECURE_NO_DEPRECATE.
この手法の欠点は、既存のコードが大量にある場合、新しいより安全なルーチンを使用するように物事を移行するのが非常に面倒になる可能性があることです。危険と見なされる機能を取り除くまで、気が狂ってしまう可能性があります。
valgrind過去の動的に割り当てられたデータの書き込みを検出しますが、あなたの例のような自動配列では検出できないと思います。strcat、などを使用している場合はstrcpy、宛先が十分に大きいことを確認する必要があります。
編集:私はvalgrindについて正しかったが、いくつかの希望がある:
残念ながら、Memcheck は静的配列またはスタック配列の境界チェックを行いません。したいのですが、Memcheck の動作に適合する合理的な方法で行うことは不可能です。ごめん。
しかし、実験ツールの Ptrcheck は、このようなエラーを検出できます。オプションを指定して Valgrind を実行し
--tool=exp-ptrcheckてみてください。ただし、Memcheck ほど堅牢ではないことに注意してください。
私はPtrcheckを使用していません。
この C++ にタグを付けたのに、なぜ char へのポインターを使用するのでしょうか?
std::stringstream test;
std::fill_n(std::ostream_iterator<std::string>(test), 100, "hi");
/RTCs コンパイラ スイッチを有効にすると、このような問題をキャッチするのに役立つ場合があります。このスイッチをオンにすると、テストをstrcat1 回だけ実行したときにアクセス違反が発生しました。
このような問題に役立つもう 1 つの便利なユーティリティ (スタックよりもヒープ指向ですが、非常に役立ちます) は、application verifierです。これは無料で、ヒープ オーバーフローに関連する多くの問題をキャッチできます。
コンパイラが役立つ場合があります。たとえば、Visual Studio 2008 では、プロジェクト プロパティ - C/C++ - コード生成ページを確認します。「バッファセキュリティチェック」オプションがあります。
私の推測では、少し余分なメモリが確保され、そこに既知のシーケンスが書き込まれます。そのシーケンスが変更されると、バッファ オーバーランが想定されます。確かではありませんが、これをどこかで読んだことは覚えていますが、それが VC++ に関するものだったかどうかははっきりとは覚えていません。
別の方法:メモリ安全性チェッカー。このケースは対応してくれると思います。
問題は、API Validation サブシステムがデフォルトで有効になっておらず、関心のあるメッセージがそこから来るということでした。
古いバージョンの BoundsChecker について話すことはできませんが、バージョン 10.5 はこのテストで特に問題はありません。正しい結果が報告され、BoundsChecker 自体はクラッシュしません。ただし、この特定のテスト ケースは、テスト コードがあった関数につながるコール スタックを完全に破壊し、その関数が終了するとすぐに、アプリケーションも破壊するためです。
結果: ローカル変数への書き込みオーバーランに関する 100 件のメッセージと、null で終了していない宛先文字列に関する 99 件のメッセージ。技術的には、その 2 番目のメッセージは正しくありませんが、BoundsChecker は宛先文字列自体の境界内でのみ null 終端を検索し、最初の strcat 呼び出しの後、その境界内にゼロ バイトが含まれなくなります。
免責事項: 私は MicroFocus で BoundsChecker の開発者として働いています。