16

I have this code segment in which I am opening/closing a file a number of times (in a loop):

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*/
     }

I get a SIGABRT here, with the following backtrace:

#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

The line number 1100, is the line where I am doing the fclose() in the above code segment. What is the reason for the above behavior? Any pointers is appreciated.

(I am on Linux and using gcc)

  • 1
    Your are using the same i in both of your loops, is that intentional? – IVlad Feb 25 '10 at 13:51
  • @IVlad: Thanks for pointing it out. It was an error in the question posting. Fixed it. –  Feb 25 '10 at 13:52
  • What's with the malloc_printerr message? Are you sure the fclose() is causing the crash? I think you should reduce your code to exactly the part that causes the problem and post that... – IVlad Feb 25 '10 at 13:57
  • Well, as the backtrace shows, the crash was caused at line 1100, which is my fclose() line, if I remove that line, it runs fine. –  Feb 25 '10 at 14:00
  • What happens if you move the fopen before the first for (the one with i) and the fclose after it? The way this is now your all_fitness.out file will get overwritten at each iteration of i, which is not what you want, I'm guessing? – IVlad Feb 25 '10 at 14:04
  • That's what I want: the file contents should be over-written every iteration. –  Feb 25 '10 at 14:09
  • Hello, I tried to complete your code snippet with some variables, but no error occurred. Can your code be more detailed?? – coelhudo Feb 25 '10 at 14:52
  • Curious -- what's the value of i at the time of abort? Is it the first, last, or somewhere in the middle (and is that consistent between runs)? – Walt Stoneburner Feb 25 '10 at 17:35
  • Also, are there any other threads doing anything at the same time? The "str=0x6
    " part of the message makes me wonder if something is getting corrupted along the way.
    – Walt Stoneburner Feb 25 '10 at 17:37
  • You want `oldpop[j]` instead of `oldpop[i]` - not sure if this is a copy-paste error or a bug in your code. – Alok Singhal Feb 25 '10 at 18:49

2 Answers2

23

When you call fclose(), glibc releases some dynamically allocated structures; internally there is a free() call. malloc() and free() rely on rather complex, dynamically built structures. Apparently, glibc found that the structures were in an incoherent state, to the point that safe memory release cannot be done. glibc decided that the problem was serious enough to warrant an immediate abort.

This means that you have a bug somewhere in your code, possibly quite far from the snippet you show, a buffer overflow or a similar out-of-place memory write which damages the memory allocation structures.

You may want to try Valgrind or Electric Fence to sort such problems out.

Thomas Pornin
  • 72,986
  • 14
  • 147
  • 189
  • Hello Thomas: Yes, the bug was somewhere else. Valgrind helped me figure it out. So, thanks for your hint. After your answer, I really dug into the code, and have corrected a rather stupid, overlooked mistake. –  Feb 25 '10 at 18:54
1

I don't know if it's causing your particular problem, but you should always check the FILE * pointer returned by fopen() in case it's NULL.

Simon Nickerson
  • 42,159
  • 20
  • 102
  • 127