free():fclose 上的下一个大小(正常)无效。但不是在 Valgrind 运行时[重复]

Posted

技术标签:

【中文标题】free():fclose 上的下一个大小(正常)无效。但不是在 Valgrind 运行时[重复]【英文标题】:free(): invalid next size (normal) on fclose. But not when Valgrind runs [duplicate] 【发布时间】:2013-01-16 03:42:07 【问题描述】:

下面的代码在fclose() 调用中中断。

void output_gauss_transform(char* filename, char* mode, double** T, 
                            double shift, int len)

    FILE* fp;

    printf("Outputting gauss transform to %s.\n", filename);

    if ((fp = fopen(filename, mode)) == NULL)
    perror("Could not open file");
    return;
    

    int i;

    for (i = 0; i < len; ++i) 
    fprintf(fp, "%lf %lf\n", T[0][i], T[1][i] + shift);
    

    if (fclose(fp))
    printf("error closing\n");
    

glibc 给了我这个错误以及内存映射。

*** glibc detected *** [sourcedir]/.libs/lt-launcher: free(): invalid next size (normal): 0x0821da38 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb739dee2]
/lib/i386-linux-gnu/libc.so.6(fclose+0x154)[0xb738d424]
/src/.libs/libfile_util.so.0(output_gauss_transform+0xa9)[0xb77b5859]
/src/.libs/lt-launcher[0x804a0f9]
/src/.libs/lt-launcher[0x804a2a5]
/src/.libs/lt-launcher[0x804983b]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb73414d3]
/src/.libs/lt-launcher[0x8049915]

当尝试使用valgrind 进行调试时,我没有收到任何错误,它会输出以下内容。到底是怎么回事?

==30396== HEAP SUMMARY:
==30396==     in use at exit: 0 bytes in 0 blocks
==30396==   total heap usage: 1,059 allocs, 1,059 frees, 78,149 bytes allocated
==30396== 
==30396== All heap blocks were freed -- no leaks are possible
==30396== 
==30396== For counts of detected and suppressed errors, rerun with: -v
==30396== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

编辑:运行valgrind-v,最后我得到了这个东西。也许它与正在发生的事情有关?

 --31325-- REDIR: 0x454cac0 (operator delete(void*)) redirected to 0x402bb98 (operator delete(void*))

【问题讨论】:

【参考方案1】:

这段代码是受害者,你需要找到肇事者。当您调用fclose 时,会释放一些结构。此时,代码发现空闲池已损坏并报告错误。但是,破坏空闲池的是其他代码块,而不是这段代码。

此错误的最常见原因是两次释放同一块内存并在释放后访问一块内存。 valgrind 无法捕捉到这一点很奇怪,因为这些正是它通常捕捉到的错误类型。

【讨论】:

是否有任何开关可以让 Valgrind 的检查更加严格? 看看--redzone-size--freelist-vol。您的程序是否对内存分配做了任何奇怪的事情? (例如,从库中获取一个对象,然后它必须释放它,实现它自己的“重新使用最近释放的对象”行为,或者类似的东西?)

以上是关于free():fclose 上的下一个大小(正常)无效。但不是在 Valgrind 运行时[重复]的主要内容,如果未能解决你的问题,请参考以下文章

nepctf-pwn

SylixOS free命令实现过程

utl_file.FCLOSE() 处理大文件时速度很慢

C 错误 - free():下一个大小无效(快速)

malloc() 和 free() 在哪里存储分配的大小和地址?

Tomcat 7 - 无法使 CATALINA_OPTS 堆大小正常工作