2

次のように、C++ アプリケーションにバッファー クラスがあります。

class Buffer
{
    public:
    Buffer(size_t res): _rpos(0), _wpos(0)
    {
        _storage.reserve(res);
    }

    protected:
    size_t _rpos, _wpos;
    std::vector<uint8> _storage;
}

必要なメモリ領域を割り当てることができないため、コンストラクターの使用が失敗することがあります。たとえば、一度、コンストラクターを呼び出すと、res = 37コア ダンプから取得した次のスタック トレースでセグメンテーション違反が発生しました。

#0  0x00007f916a176ed5 in raise () from /lib/libc.so.6
No symbol table info available.
#1  0x00007f916a1783f3 in abort () from /lib/libc.so.6
No symbol table info available.
#2  0x00007f916a1b33a8 in ?? () from /lib/libc.so.6
No symbol table info available.
#3  0x00007f916a1b8948 in ?? () from /lib/libc.so.6
No symbol table info available.
#4  0x00007f916a1bb17c in ?? () from /lib/libc.so.6
No symbol table info available.
#5  0x00007f916a1bca78 in malloc () from /lib/libc.so.6
No symbol table info available.
#6  0x00007f916ac0c16d in operator new (sz=37)
    at ../../.././libstdc++-v3/libsupc++/new_op.cc:52
        p = <value optimized out>
#7  0x00000000004e3d11 in std::vector<unsigned char, std::allocator<unsigned char> >::reserve (this=0x7f911bc49cc0, __n=31077)
    at /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.4.2/../../../../include/c++/4.4.2/ext/new_allocator.h:89
        __old_size = 0
        __tmp = <value optimized out>

GCC 4.4.2 を使用してこのアプリケーションを 64 ビット アプリケーションとしてコンパイルし、Debian 5 x64 で使用しています。

どんな助けでも大歓迎です。ありがとう

4

2 に答える 2

8

segfault は malloc にあるため、他のコードがヒープを破棄した可能性があります (つまり、所有していないメモリの一部に書き込まれ、ヒープ マネージャーによって使用されています)。

Valgrindを使用して、ヒープを破壊しているコードを見つけることをお勧めします。

于 2009-12-26T09:06:47.550 に答える
2

Valgrind を使用してメモリが壊れている場所を見つけることができない場合は、負荷が高いことを意味しますが、より軽いソリューションでテストすることはできます。

(プラットフォームが Solaris 8 上にあったため) Valgrind が適用されなかったサーバー アプリケーションの場合、mpatrol ( http://mpatrol.sf.net )、特に dmalloc ( http://dmalloc.com ) でかなり良い結果が得られました。

ある程度までは、再コンパイルせずにそれらを使用できます (dmalloc の再リンク、mpatrol のライブラリのプリロードのみ)。メモリ プリミティブを置き換えて、メモリの使用に関する追加のチェックを実行します (これらのプリミティブへの不適切な引数、オフバイワンの読み取り、ヒープの破損など)。実際の悪いコードより少し遅れてトリガーされます。有効にするチェックを調整し、該当する場合はチェック頻度を調整することで、基本的なチェックを実行しながらほぼフル スピードで実行できます。

いわゆる「FUNC_CHECK」を取得するために、dmalloc を使用して再コンパイルすることをお勧めします。

于 2009-12-26T19:54:54.757 に答える