1

以下の calloc() 呼び出しでクラッシュする以下のような C コードがあります。

... some code
free (ipl->fldptr);
ipl->fldptr = calloc (flds*4, sizeof(struct fldptr_type));
...some more code

私はそれをgdbしようとしましたが、クラッシュ時に以下のバックトレースを取得しました:

Program received signal SIGSEGV, Segmentation fault.
0x0000003ade478f94 in _int_malloc () from /lib/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.7.el6.x86_64 libgcc-4.4.4-13.el6.x86_64 libstdc++-4.4.4-13.el6.x86_64
(gdb) bt
#0  0x0000003ade478f94 in _int_malloc () from /lib/libc.so.6
#1  0x0000003ade4796d8 in calloc () from /lib/libc.so.6
#2  0x0000000000daf00d in myfunction (ipl=0x106f75f0, flds=11)
    at myfile.c:1286

デバッグの一環として、gdb プロンプトで次のことを行います。

フレーム 2 に移動して、そのユーザー コード スタック フレームに移動し、変数 (flds、ポインター (ipl)) の値を出力すると、問題ないように見えます。明らかに NULL の逆参照はありません。

しかし、それでも calloc() は失敗し、そこでクラッシュします。このコードは、以前は複数回正常に実行されていましたが、後でアプリケーションをしばらく実行するとクラッシュします。(メモリリーク?? valgrindを実行しようとしますが、valgrind memcheckツールで実行すると、コードクラッシュの動作が再現できなくなります)

これをデバッグして修正するのに役立つポインタを探しています。

関連する情報 - gcc: 4.4.4 。Red Hat Enterprise Linux サーバー 6.0 64 ビット Linux

4

1 に答える 1

4

おそらく破損したヒープがあります。たとえば、free-d が早すぎた (そしてまだ再利用されている) メモリ、またはバッファ オーバーフロー (または のような無効なアクセスptr[-3])があります。

このような問題をデバッグするには、 valgrindを使用する必要があります。

Boehm の保守的なガベージ コレクターを使用することもできます。

また、 を使用して、そのようなバグを手動で探すこともできますgdbwatchgdb コマンドを使用し、アドレス空間レイアウトのランダム化を無効にすると役立つはずです。

また、-d を使用しているポインターを常にクリアすることをお勧めします。そのため、コード内のすべての場所 をにfree置き換えます (誤って逆参照された場合は、すぐにを取得します)。free(x)free(x), x=NULLxSIGSEGV

スタック保護機能を備えた最新バージョンの GCC (現在のバージョンは 4.7) を使用することもできます。この質問を参照してください。

于 2012-05-01T14:56:27.673 に答える