在malloc.c中的SIGABRT,刚刚发生了什么?

时间:2012-11-01 16:19:11

标签: c malloc runtime-error sigabrt cgdb

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

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

从debug(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) 
可以有人想象,这里出了什么问题?我知道有两种功能可以将两个字符串组合在一起,但我想自己做!

亲切的问候。

3 个答案:

答案 0 :(得分:10)

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

实际上,你的陈述

  result = (char*) malloc( newalloc_size );

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

  result = malloc(newalloc_size+1);

但您应该学会使用asprintf

答案 1 :(得分:4)

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

尝试使用此代替您拥有的行:

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

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

答案 2 :(得分:-1)

我试图分配太多内存并得到了恶意错误(错误代码:EXC_I386_INVOP)。

我通过产品/方案/编辑方案中的诊断工具(在XCode 6.1.1中)跟踪它,然后在运行/诊断中跟踪它。