【问题标题】:SIGABRT in malloc.c, what just happened?malloc.c 中的 SIGABRT,刚刚发生了什么?
【发布时间】:2012-10-22 06:52:17
【问题描述】:

我写了这段无辜的代码,导致了这样一个邪恶的错误:

static char * prefixed( char * pref, char *str ) {
    size_t newalloc_size = sizeof(char) * (strlen(pref) + strlen(str));
    char * result = (char*) malloc( newalloc_size );
    [...]

调试输出(cgdb):

Breakpoint 1, prefixed (pref=0x401345 "Env: ", str=0x4012b5 "Home") at ./src/backend/os/env.c:77
(gdb) s
(gdb) p newalloc_size 
$1 = 9
(gdb) s
envtest: malloc.c:2368: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >=
(unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)'
failed.

Program received signal SIGABRT, Aborted.
0x00007ffff7a68fd5 in raise () from /usr/lib/libc.so.6
(gdb)  

我也检查了传递的参数。他们应该在哪里:

Breakpoint 1, prefixed (pref=0x401345 "Env: ", str=0x4012b5 "Home") at ./src/backend/os/env.c:77
(gdb) p pref
$2 = 0x401345 "Env: "
(gdb) p strlen(pref)
$3 = 5
(gdb) p str
$4 = 0x4012b5 "Home"
(gdb) p strlen(str)
$5 = 4
(gdb) 

谁能想象,这里出了什么问题?我知道有一些函数可以将两个字符串组合在一起,但我想自己做!

亲切的问候。

【问题讨论】:

  • 这看起来像堆损坏。实际的错误可能在代码中的任何地方,可能离该块很远。
  • Libc 惩罚了你抛出malloc() 的返回值。
  • 顺便说一句:newalloc_size = ... + 1 允许终止0

标签: c malloc runtime-error sigabrt cgdb


【解决方案1】:

这闻起来像是程序中的内存泄漏或缓冲区溢出(或其他一些堆损坏)其他地方。我建议使用-Wall -g 选项将其重新编译为gcc,以改进您的程序直到编译器没有给出警告,并使用valgrindgdb 来调试问题。

其实你的说法

  result = (char*) malloc( newalloc_size );

错误(终止空字节的空间不足)。你可能想要

  result = malloc(newalloc_size+1);

但你应该学会使用asprintf

【讨论】:

  • valgrind 真的是去这里的路。
  • 谢谢。缺少的零字符没有添加到上面的代码中,但已经在我的代码中了。刚刚在添加 +1 之前复制!不管怎样,谢谢!我会看看 valgrind 和 asprintf。
【解决方案2】:

从您的代码中,最可能的答案是您正在使用以 null 结尾的字符串,并且在分配的缓冲区中不允许空间用于终止 null。

试试这个而不是你拥有的那一行:

size_t newalloc_size = sizeof(char) * (strlen(pref) + strlen(str) + 1);

终止的 null 被写入 malloc 的缓冲区之外,它可能会覆盖 malloc 的内部簿记的一部分。这将导致堆损坏,迟早会导致 malloc 中断。

【讨论】:

    【解决方案3】:

    我试图分配过多的内存并且也得到了邪恶的错误(错误代码:EXC_I386_INVOP)。

    我通过 Product/Scheme/Edit Scheme... 中的诊断工具(在 XCode 6.1.1 中)对其进行了跟踪,然后在 Run/Diagnosis 中进行了跟踪。

    【讨论】:

      猜你喜欢
      • 2011-04-25
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      • 2010-11-15
      • 2020-05-21
      相关资源
      最近更新 更多