私は得ています
*** glibc が検出されました *** (/my/program/...): malloc(): メモリ破損: 0xf28000fa ***
私は valgrind の下で実行しました。これは、解放されたメモリの読み取りのケースを報告しますが、不正なメモリ書き込みのケースは報告しません。
解放されたメモリを読み取ると、メモリが破損する可能性がありますか? そうでない場合は、valgrind の出力以外に何か提案はありますか?
次のように、GDB を使用して、このメモリ アドレスの各書き込みを監視できます。
(gdb) watch *((int*)0xf28000fa)
次に、問題のある場所をデバッグできます。
読み取りはメモリの破損を引き起こしませんが、これが原因である可能性があるとは想像もしていない状況がたくさんあり、Valgrind は完璧なツールではありません。
メモリの問題のデバッグの詳細については、こちらを参照してください。
読み取ったメモリが破損することはありませんが、プログラムの動作に驚くほどのことはありません。
解放されたメモリの読み取りも、メモリの破損と見なされます。
現在のプロセッサではそれほど一般的ではないはずですが、読み取り操作でさえ魔法のように動作するプラットフォームで作業しました。特定の 6502 プロセッサでは I/O がマップされているため、I/O がマップされたアドレスを持つ通常の「読み取り」命令は驚くべきことを実行できます。
約 30 年前、私の悪い読み取りがメモリバンクの切り替えを引き起こしたため、私はそれに噛まれました (つまり、コードを含む領域を含むメモリのすべてのバイトが、その命令の直後に新しい異なる値を取得しました)。面白いのは、本当に「意図しない」悪い読み取りではなかったということです...これがいくつかのアセンブラー命令を節約したので、それがゴミになることを知っていたとしても、私は実際に読み取りを行いました...賢明な動きではありません.
いいえ、無効な場所を読み取っても、表示されているエラーが発生する可能性はありません。場所がアドレス空間で有効な場合は、ジャンクを読み取るだけです。そうでない場合は、セグメンテーション違反が発生します。
valgrind の出力をチェックして、無効な読み取りがどこから来ているかを確認します。これにより、本当の間違いがどこにあるのかについてのヒントが得られます。これを見つけたら、本当の犯人はそう遠くないと確信しており、おそらく無効な書き込みです。
実際に起こり得ることは、free が madvise(MADV_DONTNEED) syscall を使用してカーネルに「このページは必要ないので削除してください」と伝えることができるということです (madvise(2) マンページを参照)。そのページの割り当てが実際に解除され、そこから何かを読み取った場合、カーネルは静かに新しいページを提供し、ゼロにします。そのため、アプリケーションはまったく予期しないデータに遭遇します!