当传递指向已释放内存块的指针时,mprobe return 应该做什么?

What should mprobe return when it is passed a pointer to a freed block of memory?

GNU libc manual page for mcheck says that the MCHECK_FREE status means "The block was already freed." That would imply to me that the block was freed (at least) once. This answer seems to imply the same in the code example. However, the Linux manpage 非常明确地说 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 的不同实现会 return MCHECK_FREE 而不是?

我通过电子邮件发送了一个 libc 开发人员邮件列表。我把我的问题分成了 2 个问题,每个问题都得到了回应:

  1. 哪个手册(GNU 或 Linux)关于 MCHECK_FREE 是正确的?

They are both correct, but written from slightly different perspectives.

If the block was previously free'd then you should return MCHECK_FREE.

However, if you can't detect that it was previously free'd because of corruption then you might only be able to return MCHECK_HEAD as the default results if the corruption has changed all co-located metadata about the state information.

  1. [当在释放的指针上调用 mprobe 时]通常期望返回 MCHECK_HEAD 是否合理?

Yes.