100

我正在实现一个分而治之的多项式算法,因此我可以将它与 OpenCL 实现进行基准测试,但我无法开始malloc工作。当我运行程序时,它会分配一堆东西,检查一些东西,然后将它们发送size/2给算法。然后,当我malloc再次上线时,它会吐出:

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

有问题的行是:

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);
}

我用 a 检查了大小fprintf,它是一个正整数(此时通常为 50)。我也尝试malloc使用普通号码拨打电话,但仍然收到错误消息。我只是对正在发生的事情感到困惑,到目前为止我发现谷歌没有任何帮助。

有什么想法吗?我试图弄清楚如何编译一个更新的 GCC,以防它是一个编译器错误,但我真的怀疑它。

4

8 回答 8

113

99.9% 的可能性是您的内存已损坏(缓冲区溢出或不足、在指针被释放后写入指针、在同一指针上调用两次 free 等)

在Valgrind下运行你的代码,看看你的程序在哪里做错了。

于 2010-06-07T05:20:19.287 回答
91
于 2013-10-14T17:41:38.627 回答
23

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

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

我使用Address Sanitizer编译了他的程序

gcc -Wall -g3 -fsanitize=address -o new new.c
              ^^^^^^^^^^^^^^^^^^

然后跑了gdb new。当程序SIGABRT在后续中被 cause 终止时malloc(),会打印很多有用的信息:

=================================================================
==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. 那行写着

memset(len,0,sizeof(int*)*p);
             ^^^^^^^^^^^^

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

if(!(len=(int*)malloc(sizeof(int)*p))){
                      ^^^^^^^^^^^

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

总结:试试-fsanitize=addressGCC 或 Clang 的。在调试内存问题时非常有用。

于 2018-12-25T14:43:57.687 回答
2

您可能超出了某处分配的内存。那么在你调用 malloc 之前,底层的 sw 不会接受它

可能有一个守卫值被 malloc 捕获。

编辑...为边界检查帮助添加了这个

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

于 2010-06-07T06:25:20.760 回答
2

我收到以下消息,类似于您的消息:

    程序:malloc.c:2372: sysmalloc: 断言`(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)' 失败。

之前在使用 malloc 时犯了一些方法调用错误。在 sizeof()-operator 添加字段到 unsigned char 数组后更新因子时,错误地用 '+' 覆盖了乘号 '*'。

在我的案例中,这是导致错误的代码:

    UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)+5);
    b[INTBITS]=(一些计算);
    b[BUFSPC]=(一些计算);
    b[BUFOVR]=(一些计算);
    b[BUFMEM]=(一些计算);
    b[MATCHBITS]=(一些计算);

后来在另一种方法中,我再次使用了 malloc,它产生了上面显示的错误消息。电话是(很简单):

    UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)*50);

考虑在第一次调用时使用“+”符号,这会导致计算错误,再加上数组的立即初始化(覆盖未分配给数组的内存),给 malloc 的内存映射带来了一些混乱。因此第二次调用出错了。

于 2016-10-31T14:45:22.583 回答
0

我们得到这个错误是因为我们忘记乘以 sizeof(int)。注意 malloc(..) 的参数是字节数,而不是机器字数或其他。

于 2011-05-02T23:42:36.550 回答
0
于 2017-04-26T17:53:34.610 回答
-1

我正在通过 Linux 将一个应用程序从 Visual C 移植到 gcc,我遇到了同样的问题

malloc.c:3096: SYSMALLOc: 在 UBUNTU 11 上使用 gcc 的断言。

我将相同的代码移动到 Suse 发行版(在其他计算机上),我没有任何问题。

我怀疑问题不在我们的程序中,而是在我们自己的 libc 中。

于 2012-02-05T00:03:10.000 回答