valgrind は有用なものを見つけることができません。よくわかりません。
症状:
- malloc() 呼び出しによってデータが破損した
- 私の関数の戻りアドレスが何か間違って置き換えられました
PS: コードはセグメンテーション違反をしません
現在、すべての malloc() をmmap()
+で置き換えることで、ある程度の進歩がありますmprotect()
valgrind は有用なものを見つけることができません。よくわかりません。
症状:
PS: コードはセグメンテーション違反をしません
現在、すべての malloc() をmmap()
+で置き換えることで、ある程度の進歩がありますmprotect()
スタックを上書きしているか、ヒープを上書きしている可能性があります。
フラグ-fstack-protector-all
を GCC コマンド ライン オプションに追加して、スタック破壊レポートをプログラムに組み込むように要求することができます。これにより、より早く失敗する可能性があります。
別の可能性は、出力で報告されたアドレスを見て、破壊されdmesg
ている関数/メモリを追跡できないかどうかを確認することです。
[68303.941351] broken[13301]: segfault at 7f0061616161 ip 000000000040053d sp 00007fffd4ad3980 error 4 in broken[400000+1000]
readelf -s
シンボルテーブルをダンプすると、問題を引き起こしている関数を探すことができます:
$ readelf -s broken | grep 4005
40: 00000000004005e0 0 FUNC LOCAL DEFAULT 13 __do_global_ctors_aux
47: 0000000000400540 2 FUNC GLOBAL DEFAULT 13 __libc_csu_fini
57: 0000000000400550 137 FUNC GLOBAL DEFAULT 13 __libc_csu_init
63: 0000000000400515 42 FUNC GLOBAL DEFAULT 13 main
このmain
ルーチンは、不良ポインターが使用されたときに実行されるものです。
#include <string.h>
void f(const char *s) {
char buf[4];
strcpy(buf, s);
return;
}
int main(int argc, char* argv[]) {
f("aaaa");
f("aaaaaaaaaaaaaaaaaaaa");
return 0;
}
main
終了するために C ライブラリに戻ろうとすると、スタック フレームに格納された不正なポインタが使用されます。によって呼び出される関数を見てください。main
(この些細なケースでは非常に簡単です)f
は明らかに、スタック フレーム全体に落書きされたバグです。
ヒープを上書きしている場合は、おそらく電気フェンスを試すことができます。マイナス面はかなり急です (大量のメモリを使用します) が、問題を見つけるために必要なものかもしれません。
IBM Rational Purify の試用版を試すこともできます。これは、バッファー オーバーフロー、メモリ リーク、およびその他のメモリ破損エラーを検出するための非常に優れたツールです。このリンクに従ってダウンロードしてください http://www-01.ibm.com/software/awdtools/purify/unix/
Valgrind memcheck は、バッファ オーバーランの検出にはあまり適していません。しかし、可能性のあるパッチを試すことができます。
次のリンクを参照してください::どの C/C++ ツールでバッファ オーバーフローをチェックできますか?
どのような環境で開発していますか?
Windows で開発している場合は、この記事http://msdn.microsoft.com/en-us/library/cc500347.aspxを試してください。
Linux では役に立ちません。しかし、文字列関数を使用していないということは、アプリケーションがかなり移植可能である可能性があることを示唆しています。Windows では失敗しますか?
その場合、CheckPointerツールで問題を検出できる可能性があります。コード内の構造と宣言を確認でき、さまざまな種類のストレージの使用 (スタック フレームとヒープ) を理解できるため、Valgrind よりもプログラムがポインターを使用する方法をより注意深くチェックします。Valgrind はマシン命令のみを認識し、スタック フレームがいつスコープ外になるかを判断できません。