简体   繁体   English

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

[英]SIGABRT in malloc.c, what just happened?

I wrote this innocent piece of code, and results in such an evil error: 我写了这段无辜的代码,导致了这样一个邪恶的错误:

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

output from debug (cgdb): 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)  

I checked the passed arguments, too. 我也检查了传递的参数。 They where just as they are supposed to be: 它们就像它们应该是:

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) 

can anybody imagine, what goes wrong here? 任何人都可以想象,这里出了什么问题? I know there are functions to cat two strings together, but I want to do it on my own! 我知道有两个功能可以将两个字符串组合在一起,但我想自己做!

kind regards. 亲切的问候。

This smells like a memory leak or buffer overflow (or some other heap corruption) elsewhere in your program. 这有点像程序中其他地方的内存泄漏或缓冲区溢出(或其他一些堆损坏)。 I suggest to recompile it using the -Wall -g options to gcc , to improve your program till no warnings are given by the compiler, and to use valgrind and gdb to debug the issue. 我建议使用-Wall -g选项重新编译它到gcc ,改进程序,直到编译器没有给出警告,并使用valgrindgdb来调试问题。

Actually, your statement 实际上,你的陈述

  result = (char*) malloc( newalloc_size );

is wrong (lack of space for the terminating null byte). 是错误的(终止空字节的空间不足)。 You probably want 你可能想要

  result = malloc(newalloc_size+1);

but you should learn to use asprintf 但你应该学习使用asprintf

From your code, the most likely answer is that you are using null-terminated strings and not allowing space for the terminating null in the buffer you allocate. 从您的代码中,最可能的答案是您使用以null结尾的字符串,并且不允许在您分配的缓冲区中为终止null留出空间。

Try this instead of the line you have: 试试这个而不是你拥有的那条线:

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

The terminating null is being written outside of your malloc'd buffer, where it is probably overwriting part of malloc's internal bookkeeping. 终止null是在malloc缓冲区之外写的,它可能会覆盖malloc内部簿记的一部分。 This will cause heap corruption, which will sooner or later cause malloc to break. 这将导致堆损坏,这迟早会导致malloc中断。

I was trying to allocate too much memory and got the evil error too (error code: EXC_I386_INVOP). 我试图分配太多内存并得到了邪恶的错误(错误代码:EXC_I386_INVOP)。

I tracked it down through the diagnosis tools (in XCode 6.1.1) in Product/Scheme/Edit Scheme... and then in Run/Diagnosis. 我通过产品/方案/编辑方案中的诊断工具(在XCode 6.1.1中)跟踪它,然后在运行/诊断中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM