为啥会生成此核心转储

Posted

技术标签:

【中文标题】为啥会生成此核心转储【英文标题】:Why this core dumped is generated为什么会生成此核心转储 【发布时间】:2013-04-22 00:09:36 【问题描述】:

我正在编写一个 C 程序,其相关细节如下:

void calculate(struct iso_matrix *iso_matrix) 
        struct graphlet *graphlet = init_graphlet(GL_SIZE);
        int *index_map = (int *)malloc(iso_matrix->n_rw_col);
        //some other stuff. Working fine.
        free(index_map);    //line 90(for future references)

我在终端得到的输出:

*** glibc detected *** ./bin/exec: free(): invalid next size (fast):0x00000000023696f0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x2b3b5fc92b96]
./bin/exec[0x403ff9]
./bin/exec[0x4049eb]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x2b3b5fc3576d]
./bin/exec[0x400889]
======= Memory map: ========
(not shown here)

而 GDB 回溯是:

#0  0x00007ffff7a51425 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff7a54b8b in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007ffff7a8f39e in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#3  0x00007ffff7a99b96 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4  0x0000000000403ff9 in calculate (iso_matrix=0x6084a0) at src/graphlet_iso_mat.c:90
#5  0x00000000004049eb in main (argc=3, argv=0x7fffffffdef8) at src/main.c:70

我无法理解为什么会发生这种情况或如何调试它。任何帮助表示赞赏。

[编辑] 完成calculate 函数:

void calculate(struct iso_matrix *iso_matrix)

    printf("Calculate called\n");
    struct graphlet *graphlet = init_graphlet(GL_SIZE);
    int *index_map = (int *)malloc(iso_matrix->n_rw_col);
    struct graph *graph = init_graph(0, GL_SIZE);   /*Small graph so prefered matrix representation.*/

    /*Initialize the list_head.*/
    if(!iso_matrix->unique)
        iso_matrix->unique = init_listhead();

    for(int i=0; i<iso_matrix->n_rw_col; ++i)
    
        graphlet_to_graph(graphlet, graph);
        calc_heuristic(graph, 3);

        /*check_unique() compares only between same type of graphs.*/
        index_map[i] = check_unique(iso_matrix->unique, graph);
        if(index_map[i]==-1)
        
            struct graph *cpy=init_graph(0, GL_SIZE);
            cpy_graph(graph, cpy);
            int *graphlet_no = (int *)malloc(sizeof(int));
            *graphlet_no = i;
            struct container *container = (struct container *)malloc(sizeof(struct container));
            container->data = (void *)cpy;
            container->id = (void *)graphlet_no;
            struct list_node *list_node = init_listnode((void *)container);
            add_to_list(list_node, iso_matrix->unique);
        
        else
        
            *(*((iso_matrix->iso_mat)+index_map[i])+i) = 1;
        

        inc_graphlet(graphlet);
        reset_graph(graph);
    

    for(int i=0; i<iso_matrix->n_rw_col; ++i)
    
        if(index_map[i]==-1)    /*If same then continue.*/
            continue;
        for(int j=0; j<iso_matrix->n_rw_col; ++j)
            *(*((iso_matrix->iso_mat)+i)+j) = *(*((iso_matrix->iso_mat)+index_map[i])+j);
    

    /*Destroying allocated memory.*/
    free(index_map);

【问题讨论】:

这可能是某个地方的缓冲区溢出。内存分配和释放通常会检测堆结构中的损坏并发出警告和断言。如果可能,在free 之前中断调试器并查看index_map 周围的内存。您可能在为index_map 分配的内存之前的空间中覆盖了一个动态分配的缓冲区。 它告诉你 free() 获得了一个指向看起来不像来自 malloc() 的东西的指针。可能“//其他一些东西”部分中的某些内容要么与指针混淆,要么覆盖它不应该的内存。仅仅因为代码有效,并不意味着它是正确的。 :-) 我检查了代码,看起来我没有覆盖一些东西。你能指点一下我可以从哪里阅读这种形式的调试是使用 GDB 完成的。我也是 GDB 的新手。另请参阅编辑后的问题。 我已经有太多年没有使用GDB了。查看other questions related to invalid next size errors 了解更多信息。如果您释放未分配的内存或多次释放相同的内存,也会发生这种情况。看看GDB manual as well。我依稀记得使用“检查”或x 命令来浏览记忆。 【参考方案1】:

我打赌这个:

int *index_map = (int *)malloc(iso_matrix->n_rw_col);

意味着指向iso_matrix-&gt;n_rw_col 整数的分配。您忘记了字节计算中整数的大小:

int *index_map = malloc(iso_matrix->n_rw_col * sizeof(*index_map));

可能还有其他问题,但这显然是一个大问题。注意:我还删除了 malloc() 上的演员表,你不应该在 C 代码中这样做。确保 stdlib.h 包含在此源文件顶部的 #include 列表中。

【讨论】:

@AmanDeepGautam 并非没有深入研究代码。我从不相信我没有彻底剖析过的代码,而且你有大量的函数调用是我永远不会明智的后端。但这一个非常明显。在 valgrind 下运行它以获得更高的信心。 @WhoCraig 好的。我认为还有其他非常明显的问题。谢谢。 @AmanDeepGautam 不用担心。绝对在 valgrind 下运行它。我看到很多分配,但没有匹配的免费空间,您可能在其他地方这样做,但这值得彻底清洗内存以提高您对该领域的信心。无论如何,很高兴能提供帮助。

以上是关于为啥会生成此核心转储的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的代码会出现分段/核心转储错误?

为啥我会收到“浮点异常(核心转储)”?

为啥我的代码中出现分段错误(核心转储)错误?

为啥在构建 Android 11 时出现非法指令(核心转储)错误?

从附加到 ddd/dbx 的崩溃进程生成核心转储

为啥核心转储?