web-dev-qa-db-ja.com

ここでSIGABRTを取得するのはなぜですか?

私はこのコードセグメントを持っており、ファイルを何度も(ループで)開いたり閉じたりしています:

_for(i=1;i<max;i++)
     {
       /* other code */
       plot_file=fopen("all_fitness.out","w");
       for (j=0;j<pop_size;j++)
         fprintf(plot_file, "%lf %lf\n",oldpop[i].xreal[0],oldpop[i].obj);
       fclose(plot_file);
      /*other code*/
     }
_

ここでSIGABRTを取得し、次のバックトレースを示します。

_#0  0x001fc422 in __kernel_vsyscall ()
#1  0x002274d1 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#2  0x0022a932 in *__GI_abort () at abort.c:92
#3  0x0025dee5 in __libc_message (do_abort=2, fmt=0x321578 "*** glibc detected *** %s: %s: 0x%s ***\n")
    at ../sysdeps/unix/sysv/linux/libc_fatal.c:189
#4  0x00267ff1 in malloc_printerr (action=<value optimized out>, str=0x6 <Address 0x6 out of bounds>, ptr=0x8055a60) at malloc.c:6217
#5  0x002696f2 in _int_free (av=<value optimized out>, p=<value optimized out>) at malloc.c:4750
#6  0x0026c7cd in *__GI___libc_free (mem=0x8055a60) at malloc.c:3716
#7  0x0025850a in _IO_new_fclose (fp=0x8055a60) at iofclose.c:88
#8  0x0804b9c0 in main () at ga.c:1100
_

行番号1100は、上記のコードセグメントでfclose()を実行している行です。上記の動作の理由は何ですか?どんなポインタでも大歓迎です。

(私はLinuxを使用していて、gccを使用しています)

16
user59634

fclose()を呼び出すと、glibcは動的に割り当てられた構造体をいくつか解放します。内部的にはfree()呼び出しがあります。 malloc()free()は、かなり複雑で動的に構築された構造に依存しています。どうやら、glibcは、構造がインコヒーレントな状態にあり、安全なメモリ解放を実行できないことを発見しました。 glibcは、問題が深刻であり、すぐに中止する必要があると判断しました。

これは、コードのどこかにバグがあり、表示されているスニペットからかなり離れている可能性があること、バッファオーバーフロー、またはメモリ割り当て構造に損傷を与える同様の不適切なメモリ書き込みがあることを意味します。

Valgrind または Electric Fence を試して、このような問題を解決することをお勧めします。

20
Thomas Pornin

それがあなたの特定の問題を引き起こしているかどうかはわかりませんが、それがNULLの場合は、fopen()によって返されるFILE *ポインタを常にチェックする必要があります。

1
Simon Nickerson