首先,一点背景,所以你不会认为我试图做一些疯狂的事情:
我正在尝试调试由其他人编写的C库中的崩溃。崩溃看起来像这样:
TheProgram(44365,0x7fff75996310) malloc: *** error for object 0x7fb8d4b9d440: pointer being freed was not allocated
崩溃发生在我无法运行valgrind的系统上,唉。我做的第一件事就是围绕所有库对malloc(),calloc(),realloc()和free()的调用包装debug-print-mac,以便每当分配/重新分配内存时看到printf()输出被图书馆释放。从那个调试输出看来,导致free()崩溃的指针确实先前在程序中被分配了,并且在free()调用问题之前它没有被释放:
JJ_CHECK_MALLOC at [fastgr.c : 265] malloc() returned 0x7fb8d4b9d440
[...]
JJ_CHECK_FREE at [dotinit.c : 204] about to call free(0x7fb8d4b9d440)
TheProgram(44365,0x7fff75996310) malloc: *** error for object 0x7fb8d4b9d440: pointer being freed was not allocated
所以大概必须发生的是,在调用malloc()之后和调用free()之前的某个地方,堆必须以free()不再认为该指针有效的方式被破坏
然后,我需要做的是跟踪导致堆损坏的例程。我可以这样做的一种方法是在执行路径的各个位置查询指针的有效性,并缩小其状态从“有效堆指针”变为“堆管理器不知道该指针是什么”的位置。但我知道的唯一方法是找出堆管理器是否认为指针是可以自由的是调用free(),当程序仍然想要使用指针时,我显然不能这样做。有没有办法调用free()使用的check-if-pointer-is-in-heap函数,而不实际释放数据?
答案 0 :(得分:2)
一般来说:不。
有“调试堆”围绕已分配的块,并附加“fence”信息以帮助检测错误指针错误。如果你试图释放未通过它们分配的东西,这些将相当可靠地抱怨,因为围栏将会丢失。 (当然,如果你已经覆盖了缓冲区的末端并且损坏了围栏,他们也会抱怨。)在代码经常更改的环境中,尽管性能成本很高,但我有时会永久启用这些堆...但是人们希望在代码发送给客户之前通常可以关闭它们。