c - 当 mprobe 被传递一个指向已释放内存块的指针时,它应该返回什么?
问题描述
mcheck的GNU libc手册页说 MCHECK_FREE 状态意味着“块已被释放”。这对我来说意味着该块被释放(至少)一次。这个答案似乎在代码示例中暗示相同。但是,Linux 手册页非常明确地指出 MCHECK_FREE 的意思是“一块内存被释放了两次”。我从上面的答案修改了代码示例,使其更具描述性:
#include <stdio.h>
#include <stdlib.h>
#include <mcheck.h>
void print_status(enum mcheck_status status)
{
switch(status)
{
case MCHECK_DISABLED:
printf("MCHECK_DISABLED\n");
break;
case MCHECK_OK:
printf("MCHECK_OK\n");
break;
case MCHECK_HEAD:
printf("MCHECK_HEAD\n");
break;
case MCHECK_TAIL:
printf("MCHECK_TAIL\n");
break;
case MCHECK_FREE:
printf("MCHECK_FREE\n");
break;
}
}
void no_op(enum mcheck_status status) {}
int main()
{
mcheck(&no_op);
void* f = malloc(4);
print_status(mprobe(f));
free(f);
print_status(mprobe(f));
return 0;
}
当我运行此代码时,我得到以下输出:
MCHECK_OK
MCHECK_HEAD
这意味着在检查释放的块时,我显然得到了 MCHECK_HEAD 作为响应。这种行为可靠吗?期望一个块的头部在被释放时总是被破坏是否合理?是否有不同的 mcheck/mprobe 实现会返回 MCHECK_FREE?
解决方案
我通过电子邮件发送了一个 libc 开发人员邮件列表。我将我的问题分为 2 个问题,每个问题都得到了答复:
- 哪个手册(GNU 或 Linux)关于 MCHECK_FREE 是正确的?
它们都是正确的,但从略微不同的角度编写。
如果该块以前是空闲的,那么您应该返回 MCHECK_FREE。
但是,如果您无法检测到它之前由于损坏而被释放,那么您可能只能在损坏更改了有关状态信息的所有同位元数据的情况下返回 MCHECK_HEAD 作为默认结果。
- 通常期望 MCHECK_HEAD 将被返回是否合理 [在释放的指针上调用 mprobe 时]?
是的。
推荐阅读
- snowflake-cloud-data-platform - 雪花缺少 DDL 命令的定义
- node.js - NodeJs API 测试:-获取未捕获的类型错误:无法读取未定义的属性“状态”
- hash - 如何使用 HASH 对象进行 1=1 左连接
- rust - 如何通过传递另一个较小的切片来修改较大切片(或 Vec)的一部分?
- python - IndexError:索引 440 超出了 Python 中大小为 440 的轴 0 的范围
- jquery - 无法通过/使用 ajax 函数调用 Django 视图函数
- c++ - 从 CMD 编译时更改平台工具集
- c# - 如何在 LINQ 中计算累积和?
- python - yum install python27-python-devel.x86_64, policycoreutils-python-2.5-22.el7.x86_64 缺少 libapol.so 的要求
- typescript - Typescript 将对象数组映射到一个合并的对象类型类型声明