【问题标题】:Peculiar Errors with free免费的特殊错误
【发布时间】:2013-07-31 17:14:58
【问题描述】:

我目前正在调试一个我已经从事了一段时间的项目,并且遇到了一些涉及free 的疯狂错误。我不能上传代码,因为没有办法确切地知道问题出在哪里(大约 2500 行代码分成 22 个文件),但我会解释我所知道的。

首先,gdb 用于整个调试过程。错误似乎来自对free 的调用。在程序以SIGABRT 退出后,我从gdb 收到以下错误消息:

*** Error in `application': free(): invalid next size (normal): 0x08052008 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x767e2)[0xb7e467e2]
/lib/i386-linux-gnu/libc.so.6(+0x77530)[0xb7e47530]
application[0x8049aef]
application[0x804a8aa]
application[0x8048bee]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0xb7de9935]
application[0x8048a51]
======= Memory map: ========
08048000-08050000 r-xp 00000000 00:16 1571817    application
08050000-08051000 r--p 00007000 00:16 1571817    application
08051000-08052000 rw-p 00008000 00:16 1571817    application
08052000-08073000 rw-p 00000000 00:00 0          [heap]
b7d9c000-b7db7000 r-xp 00000000 08:01 1309022    /lib/i386-linux-gnu/libgcc_s.so.1
b7db7000-b7db8000 r--p 0001a000 08:01 1309022    /lib/i386-linux-gnu/libgcc_s.so.1
b7db8000-b7db9000 rw-p 0001b000 08:01 1309022    /lib/i386-linux-gnu/libgcc_s.so.1
b7dce000-b7dd0000 rw-p 00000000 00:00 0 
b7dd0000-b7f7d000 r-xp 00000000 08:01 1308997    /lib/i386-linux-gnu/libc-2.17.so
b7f7d000-b7f7f000 r--p 001ad000 08:01 1308997    /lib/i386-linux-gnu/libc-2.17.so
b7f7f000-b7f80000 rw-p 001af000 08:01 1308997    /lib/i386-linux-gnu/libc-2.17.so
b7f80000-b7f83000 rw-p 00000000 00:00 0 
b7f83000-b7fc4000 r-xp 00000000 08:01 1309045    /lib/i386-linux-gnu/libm-2.17.so
b7fc4000-b7fc5000 r--p 00040000 08:01 1309045    /lib/i386-linux-gnu/libm-2.17.so
b7fc5000-b7fc6000 rw-p 00041000 08:01 1309045    /lib/i386-linux-gnu/libm-2.17.so
b7fd9000-b7fdd000 rw-p 00000000 00:00 0 
b7fdd000-b7fde000 r-xp 00000000 00:00 0          [vdso]
b7fde000-b7ffe000 r-xp 00000000 08:01 1308973    /lib/i386-linux-gnu/ld-2.17.so
b7ffe000-b7fff000 r--p 0001f000 08:01 1308973    /lib/i386-linux-gnu/ld-2.17.so
b7fff000-b8000000 rw-p 00020000 08:01 1308973    /lib/i386-linux-gnu/ld-2.17.so
bffdf000-c0000000 rw-p 00000000 00:00 0          [stack]

它看起来像一个普通的双释放,但还有更多。当它们不包含任何内容时,我倾向于将所有全局指针设置为NULL,因此即使我双重释放它也不会导致错误。此外,由于我的应用程序处理数据加密,我自己创建了两个函数,首先覆盖内存,然后调用 free。

这个问题可能是由于读取超出范围的内存引起的吗?例如,如果我有一个 64 字节的内存块,并且不小心尝试读取第 65 字节,这会导致调用 free 时出错吗?我知道写越界,即使不是立即,也会导致错误...

我一整天都在尝试定位错误,但没有成功。 gdb 是否为我的案例提供了任何工具(除了休息、步进、继续和监视)?我能看到我的代码在内存分配和管理方面的真正作用吗?例如,有什么方法可以查看在特定指针指向的位置实际分配了多少内存?

提前感谢您的宝贵时间! :)

【问题讨论】:

  • 能显示相关代码吗?
  • 正如我所说,问题出现在我的应用程序的特定部分,但可能在任何时候引起。我一次又一次地检查了那部分,它工作正常。只有当作为一个整体工作时,程序才会崩溃。我无法上传 22 个文件! :D
  • "这个问题可能是由于从内存中读取越界引起的吗?"绝对是的,我经常看到这种情况发生
  • 您是否已经尝试过使用valgrind?我怀疑您正在写入已释放的内存或超出分配的缓冲区。
  • 我整天都在试图找出这个错误......”作为一个不合理的建议:休息一下,吃一顿美餐,看一部好电影或你的女孩/男孩,然后睡觉..然后才重新开始调试,最好使用 Valgrind。 ;-)

标签: c memory malloc runtime-error free


【解决方案1】:

这很像由于覆盖了未分配的内存而导致的内存管理损坏。

您可能想使用Valgrind 来分析这个。

【讨论】:

  • 你能详细说明一下valgrind吗?
  • Valgrind 通过在沙箱中运行程序来观察您的程序。明天你可能想在这里阅读:valgrind.org/docs/manual/QuickStart.html
  • @angel:尝试在有问题的行中添加换行符,以便每个变量都位于自己的行上。 C 不关心换行符。然后重新编译。
  • 感谢您的帮助!我完成了调试,所有错误都已更正!这个 Valgrind 实际上是对的……positions 有 64 个值,当弹出最后一个值时(像堆栈一样工作),我正在访问确实未初始化的 positions[64]。最初并没有造成问题,但如果没有被发现,可能会造成灾难性的后果......再次感谢!!!
  • ... 它应该给我一个invalid read 消息,虽然... ;)
【解决方案2】:

@alk 已经回答了,但我将这个 FYI 添加为行为不端的免费函数的另一个罪魁祸首:

如果指向已分配内存块的指针已移动到不同的位置: 例如

  char *string;
  string = malloc(10);
  string++;      //move memory pointer to location other than originally allocated  
  free(string);  //attempt to free will result in error

free 正在尝试释放一个不再指向已分配内容的指针,并且总是会抛出错误。

【讨论】:

  • 哦,谢谢。我只使用带有 [] 运算符的指针。它还会导致问题吗?
  • @angel - 我通常只使用任何类型的指针匹配对 malloc 或 calloc 调用的免费调用。 Wehn 我使用诸如之类的东西
  • @angel - 抱歉,上次尝试时一直出错。你免费用什么?你可以给我一个例子吗?我从来没有免费使用过使用 [] 创建的任何东西,那个;'因为它们不是动态分配,而是静态定义的。不需要免费。
  • 对不起,我应该解释得更好。你可能误会了。所有释放的指针首先使用malloc 分配。我使用 [] 运算符来访问它们指向的数据。因此,我不可能意外更改指针,是吗? :D
  • @angel: 不要强制转换malloc/calloc/realloc(),因为在 C 中没有必要也不推荐!
猜你喜欢
  • 2011-11-06
  • 2011-03-03
  • 2013-12-27
  • 1970-01-01
  • 2017-03-10
  • 2011-07-20
  • 1970-01-01
  • 2022-10-16
相关资源
最近更新 更多