如何在glibc中检测到双重空闲?

如何在glibc中检测到双重空闲?,c,free,glibc,C,Free,Glibc,当使用glibc时,它如何知道我是双重释放?它记录了我找到和释放的所有东西吗?它是否包含在元数据中,例如“有多空闲”知道每个分配可以释放多少空间,内存管理器会保留一些最有可能的“头”树节点或链表。当您传递给free某个不包含有效头的内容时,无法正确地将其释放。至于这些信息被保存在何处——这取决于实现,但通常放在您从malloc获得的地址之前——然而,大小和结构很可能是未知的,但至少它给出了一个想法,即对于每个分配,这个头是多么容易被破坏/损坏/覆盖等。,内存管理器保留一些最有可能的“头”树节点或

当使用glibc时,它如何知道我是双重释放?它记录了我找到和释放的所有东西吗?它是否包含在元数据中,例如“有多空闲”知道每个分配可以释放多少空间,内存管理器会保留一些最有可能的“头”树节点或链表。当您传递给free某个不包含有效头的内容时,无法正确地将其释放。至于这些信息被保存在何处——这取决于实现,但通常放在您从malloc获得的地址之前——然而,大小和结构很可能是未知的,但至少它给出了一个想法,即对于每个分配,这个头是多么容易被破坏/损坏/覆盖等。

,内存管理器保留一些最有可能的“头”树节点或链表。当您传递给free某个不包含有效头的内容时,无法正确地将其释放。至于这些信息被保存在哪里——这取决于实现,但通常放在您从malloc获得的地址之前——然而,大小和结构很可能是未知的,但至少它给出了一个想法,当您malloc某个东西时,这个头是多么容易被破坏/损坏/覆盖/等等。

,在内存块上有一个指针。你已经知道了。内存管理还在*bloc之前保留一个隐藏的头,例如跟踪bloc大小 释放指针时,标题为红色,以检查指针是否有效。自由操作也会删除标题。
如果您释放两次,则在第二次释放时标题将不再有效。因此就有了检测。

当你malloc一些东西时,你会得到一个内存块上的指针。你已经知道了。内存管理还在*bloc之前保留一个隐藏的头,例如跟踪bloc大小 释放指针时,标题为红色,以检查指针是否有效。自由操作也会删除标题。
如果您释放两次,则在第二次释放时标题将不再有效。因此进行了检测。

C语言标准说,第二次释放指针是未定义的行为。您在glibc中看到的是这种未定义行为的一种特殊情况,即发出消息的情况。大多数分配器都会跟踪分配的内容,在一定数量的情况下,它可以跟踪释放的内容。但你不能指望这种行为


C程序也可以无提示地崩溃或忽略情况或它认为必要的任何其他操作。

C语言标准规定,第二次释放指针是未定义的行为。您在glibc中看到的是这种未定义行为的一种特殊情况,即发出消息的情况。大多数分配器都会跟踪分配的内容,在一定数量的情况下,它可以跟踪释放的内容。但你不能指望这种行为

C程序也可以静默崩溃或忽略情况或它认为必要的任何其他操作。

由malloc、calloc或realloc分配的内存确实有一个用于分配的元数据,free使用该元数据取消分配分配的内存

但是,由于以下标准中未定义行为,因此不应假设如何或是否检测到双重自由

free释放ptr指向的内存空间,该空间必须由以前对malloc、calloc或realloc的调用返回。否则,或者如果之前已经调用过freeptr,则会发生未定义的行为。如果ptr为NULL,则不执行任何操作。

由malloc、calloc或realloc分配的内存确实具有用于分配的元数据,free使用该元数据取消分配分配的内存

但是,由于以下标准中未定义行为,因此不应假设如何或是否检测到双重自由


free释放ptr指向的内存空间,该空间必须由以前对malloc、calloc或realloc的调用返回。否则,或者如果之前已经调用过freeptr,则会发生未定义的行为。如果ptr为NULL,则不执行任何操作。

内存管理代码跟踪分配的内存,当您尝试释放不在分配内存中的内容时,它会知道有问题。此错误是否仅在调试模式下打印?如果您想知道,请使用UTSL!我编辑了问题和标记以减少-Wpedantic警告。内存管理代码跟踪分配的内存,当您尝试释放不在分配内存中的内容时,它会知道有问题。此错误是否仅在调试模式下打印?如果您想知道,请使用UTSL!我已经编辑了问题和标签以减少警告。问题是问行为是如何完成的,而不是为什么标准允许它或它是什么。@EricPostDischil问题从C开始,它如何知道。。。它只被标记为C,因为C不做任何s

声明除未定义外,OP应该知道。我甚至回答了它是如何完成的,通过追踪被释放的东西。你到底有什么问题,伙计?很明显这是在用glibc。一个真正的答案既可以让他们了解软件工程,也可以给他们提供信息,帮助他们确定glibc是否能够可靠地检测某些类型的bug。根据所使用的方法,glibc理论上可以保证检测到(比如)原始的16个免费调用中的任何双重免费,或者不保证,或者通过询问某些特殊接口可以获得附加信息。关键是,有一些检测方法在使用,像这样的答案是不合适的,因为它们阻止人们……追求知识。计算的意义远不止“这是C标准,保持在C标准之内,绝不超越C标准”。问题是行为是如何完成的,而不是标准为什么允许它或它是什么。@EricPostChil问题从C开始,它如何知道。。。它只被标记为C。因为C除了表示它是未定义的之外,没有其他任何语句,OP应该知道这一点。我甚至回答了它是如何完成的,通过追踪被释放的东西。你到底有什么问题,伙计?很明显这是在用glibc。一个真正的答案既可以让他们了解软件工程,也可以给他们提供信息,帮助他们确定glibc是否能够可靠地检测某些类型的bug。根据所使用的方法,glibc理论上可以保证检测到(比如)原始的16个免费调用中的任何双重免费,或者不保证,或者通过询问某些特殊接口可以获得附加信息。关键是,有一些检测方法在使用,像这样的答案是不合适的,因为它们阻止人们……追求知识。计算的意义远不止“这是C标准,不要超越它。”这是基于对内存管理器如何工作的猜测,还是对其规范或实现的实际了解?这是我在学校学到的。没有猜测,也没有说明。这是假的吗?你和我都不知道这是真是假。问题是,如果没有规范、源代码或作者母亲的说明,您就无法依赖软件。您不知道它应该做什么,也不知道它在不同的版本或不同的设置或环境中会如何变化。内存管理的不同实现以不同的方式工作。这是基于对内存管理器如何工作的猜测,还是对其规范或实现的实际了解?这是我在学校学到的。没有猜测,也没有说明。这是假的吗?你和我都不知道这是真是假。问题是,如果没有规范、源代码或作者母亲的说明,您就无法依赖软件。您不知道它应该做什么,也不知道它在不同的版本或不同的设置或环境中会如何变化。内存管理的不同实现以不同的方式工作。这是基于对内存管理器如何工作的推测还是对其规范或实现的实际了解?没有规范。一切都取决于实施。这就是大多数malloc的工作原理——至少是glibc和许多其他的。当然还有很多其他的方法——例如OpenBSD的malloc实际上在每次分配中都使用mmap。@kelter:C标准将许多事情留给实现,这一事实并不妨碍实现拥有自己的规范。不管怎样,这个答案是基于推测还是基于对实现的实际了解?使用了许多标准,但有一个简单的定义。在OP出错的情况下,这仅仅是因为标题已经标记为free'd。我在前面的评论中已经回答了这个问题。而且,经过两次评论,我仍然不明白你的意思。我所描述的行为对于glibc、uclibc和其他多少人来说都是正确的——然而,在最初的回答中,我明确指出了实现可能会有所不同。这是基于对内存管理器如何工作的推测还是对其规范或实现的实际了解?没有规范。一切都取决于实施。这就是大多数malloc的工作原理——至少是glibc和许多其他的。当然还有很多其他的方法——例如OpenBSD的malloc实际上在每次分配中都使用mmap。@kelter:C标准将许多事情留给实现,这一事实并不妨碍实现拥有自己的规范。不管怎样,这个答案是基于推测还是基于对实现的实际了解?使用了许多标准,但有一个简单的定义。在OP出错的情况下,这仅仅是因为标题已经标记为free'd。我在前面的评论中已经回答了这个问题。而且,在两次评论之后,我仍然不明白
你的观点。我所描述的行为对于glibc、uclibc以及谁知道还有多少其他人来说是正确的-然而,在最初的回答中,我明确指出了实现可能会有所不同。这并不能回答这个问题。@EricPostChil因为该行为在C标准中没有定义,所以如何检测它是不相关的。尽管如此,这个“答案”没有回答这个问题。该方法既与库实现人员相关,也与希望使用特定库功能的人员相关,例如。,那些认为检测某些错误可以帮助他们发现错误的人。我相信从C的角度来看确实如此。这并不能回答这个问题。@EricPostChil因为行为在C标准中是未定义的,所以如何检测它是不相关的。尽管如此,这个“答案”没有回答这个问题。该方法既适用于库实现人员,也适用于希望使用特定库功能的人员,例如,认为检测某些错误可以帮助他们发现错误的人员。我相信从C的角度来看,它确实适用于原始问题。
* glibc detected ./load: double free or corruption (!prev): ADDRESS **