首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么我得到一个C malloc断言失败?

为什么我得到一个C malloc断言失败?
EN

Stack Overflow用户
提问于 2010-06-07 13:15:48
回答 5查看 156.7K关注 0票数 97

我正在实现一个分而治之的多项式算法,这样我就可以根据OpenCL实现对它进行基准测试,但是我不能让malloc工作。当我运行程序时,它会分配一堆东西,检查一些东西,然后将size/2发送给算法。然后,当我再次点击malloc行时,它会显示以下内容:

代码语言:javascript
复制
malloc.c:3096: 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.
Aborted

问题所在的行是:

代码语言:javascript
复制
int *mult(int size, int *a, int *b) {
    int *out,i, j, *tmp1, *tmp2, *tmp3, *tmpa1, *tmpa2, *tmpb1, *tmpb2,d, *res1, *res2;
    fprintf(stdout, "size: %d\n", size);

    out = (int *)malloc(sizeof(int) * size * 2);
}

我用fprintf检查了大小,它是一个正整数(通常是50 )。我也尝试使用普通号码调用malloc,但仍然收到错误。我只是被正在发生的事情难住了,到目前为止,我从谷歌上发现的任何东西都没有帮助。

知道是怎么回事吗?我正在试图找出如何编译一个较新的GCC,以防它是一个编译器错误,但我真的很怀疑。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-06-07 13:20:19

99.9%的可能性是内存损坏(缓冲区溢出或下溢,释放指针后写入指针,在同一指针上调用释放两次,等等)

Valgrind下运行你的代码,看看你的程序哪里出了问题。

票数 112
EN

Stack Overflow用户

发布于 2018-12-25 22:43:58

我使用Valgrind的替代解决方案:

我很高兴,因为我刚刚帮我的朋友调试了一个程序。他的程序有这个确切的问题(malloc()导致中止),以及来自GDB的相同的错误消息。

我用Address Sanitizer编译了他的程序

代码语言:javascript
复制
gcc -Wall -g3 -fsanitize=address -o new new.c
              ^^^^^^^^^^^^^^^^^^

然后运行了gdb new。当程序因后续malloc()中的SIGABRT而终止时,将打印大量有用的信息:

代码语言:javascript
复制
=================================================================
==407==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6060000000b4 at pc 0x7ffffe49ed1a bp 0x7ffffffedc20 sp 0x7ffffffed3c8
WRITE of size 104 at 0x6060000000b4 thread T0
    #0 0x7ffffe49ed19  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x5ed19)
    #1 0x8001dab in CreatHT2 /home/wsl/Desktop/hash/new.c:59
    #2 0x80031cf in main /home/wsl/Desktop/hash/new.c:209
    #3 0x7ffffe061b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #4 0x8001679 in _start (/mnt/d/Desktop/hash/new+0x1679)

0x6060000000b4 is located 0 bytes to the right of 52-byte region [0x606000000080,0x6060000000b4)
allocated by thread T0 here:
    #0 0x7ffffe51eb50 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb50)
    #1 0x8001d56 in CreatHT2 /home/wsl/Desktop/hash/new.c:55
    #2 0x80031cf in main /home/wsl/Desktop/hash/new.c:209
    #3 0x7ffffe061b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

让我们来看看输出,特别是堆栈跟踪:

第一部分说明在new.c:59有一个无效的写操作。那行是这样写的

代码语言:javascript
复制
memset(len,0,sizeof(int*)*p);
             ^^^^^^^^^^^^

第二部分说明发生错误写入的内存是在new.c:55中创建的。那行是这样写的

代码语言:javascript
复制
if(!(len=(int*)malloc(sizeof(int)*p))){
                      ^^^^^^^^^^^

就这样。我只花了不到半分钟的时间就找到了让我的朋友困惑了几个小时的bug。他设法定位了故障,但随后的malloc()调用失败了,无法在前面的代码中发现这个错误。

总结:试一试GCC或-fsanitize=address的。它在调试内存问题时非常有用。

票数 23
EN

Stack Overflow用户

发布于 2010-06-07 14:25:21

你可能在某处超出了分配的内存。那么底层的sw直到你调用malloc时才会发现它。

可能存在被malloc捕获的保护值。

使用edit...added获取边界检查帮助

http://www.lrde.epita.fr/~akim/ccmp/doc/bounds-checking.html

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2987207

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档