为啥我会在这里获得 SIGABRT?

Posted

技术标签:

【中文标题】为啥我会在这里获得 SIGABRT?【英文标题】:Why do I get a SIGABRT here?为什么我会在这里获得 SIGABRT? 【发布时间】:2011-01-21 00:26:43 【问题描述】:

我有这个代码段,我在其中多次打开/关闭一个文件(在一个循环中):

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)

【问题讨论】:

您在两个循环中都使用相同的 i,这是故意的吗? @IVlad:感谢您指出。这是问题发布中的错误。修好了。 malloc_printerr 消息是怎么回事?您确定 fclose() 导致崩溃吗?我认为您应该将代码减少到导致问题的部分并发布... 嗯,正如回溯所示,崩溃是在第 1100 行引起的,这是我的 fclose() 行,如果我删除该行,它运行正常。 如果您将 fopen 移到第一个 for(带有 i 的那个)之前,然后将 fclose 移到它之后会发生什么?现在,您的 all_fitness.out 文件将在 i 的每次迭代中被覆盖,我猜这不是您想要的? 【参考方案1】:

调用fclose()时,glibc会释放一些动态分配的结构;内部有一个free() 调用。 malloc()free() 依赖于相当复杂的、动态构建的结构。显然,glibc 发现这些结构处于不连贯的状态,以至于无法进行安全的内存释放。 glibc 认为问题严重到需要立即中止。

这意味着您的代码中某处存在错误,可能与您显示的 sn-p 相距甚远、缓冲区溢出或类似的异地内存写入会损坏内存分配结构。

您可能想尝试Valgrind 或Electric Fence 来解决此类问题。

【讨论】:

你好 Thomas:是的,这个 bug 是在别的地方。 Valgrind 帮我解决了这个问题。所以,谢谢你的提示。在你的回答之后,我真的深入研究了代码,并纠正了一个相当愚蠢,被忽视的错误。【参考方案2】:

我不知道它是否会导致您的特定问题,但您应该始终检查fopen() 返回的FILE * 指针,以防它是NULL

【讨论】:

我已经检查过了,没什么可疑的。谢谢:)

以上是关于为啥我会在这里获得 SIGABRT?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在 for() 行上出现 EXC_CRASH (SIGABRT) 错误

CoreData SIGABRT 同时保存主 MOC。为啥?

为啥在视图控制器被取消初始化并导致 SIGABRT 或 EXC_BAD_ACCESS 后观察者仍然活着?

iPad 应用程序适用于大多数设备,在某些设备上获得 EXC_CRASH (SIGABRT)

NSMutableString appendString 生成一个 SIGABRT

Xcode:“线程 1:信号 SIGABRT”