FastMM4说“块头已被损坏” [英] FastMM4 says "The block header has been corrupted"

查看:320
本文介绍了FastMM4说“块头已被损坏”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个讨厌的错误在过去消失了,但现在经过一段时间后才返回。



我有两个TSam对象(派生自TPersistent)创建和加载转换成TAsmJob对象(派生自TObjectList)。



在运行时,表单创建一个TStringGrid,然后创建AsmJob,创建这两个SAM对象(并从磁盘加载一些数据在他们每个)。 AsmJob也被分配到网格。
当表单被销毁时,Grid通过释放它来处理AsmJob,这释放了TSam对象。这是一个问题:第一个对象被释放的问题,但是第二个对象在继承方法(在Destroy析构函数中)被调用时就会死亡。



我在整个过程中使用FreeAndNil程序释放对象。 TSAM对象不是NIL !!!!!所以,这是第一次释放对象的尝试。即使对象中的数据是一致的。



程序的主干如下所示:

  **创建:** 

表单 - > StringGrid
- > AsmJob - > Sam1,Sam2
StringGrid.AsmJob:= AsmJob;


**免费:**

表单 - > StringGrid - > AsmJob - > Sam1,Sam2

我真的不明白我在哪里尝试双重或覆盖对象它已被释放。






编辑:



我收到的错误:




  • FastMM在
    空闲块扫描操作期间检测到错误。 FastMM
    检测到一个块在被释放之后被修改为


  • FastMM在
    free期间检测到错误块扫描操作。块
    标题已被损坏。




详细信息:

 当前线程ID为0x19C,导致此错误的堆栈跟踪(返回地址)为:
402E77 [System] [@ FreeMem]
4068DC [系统] [@ DynArrayClear]
405E2D [系统] [@ FinalizeArray]
405D31 [系统] [@ FinalizeRecord]
40432F [系统] [TObject.CleanupInstance]
404272 [系统] [TObject.FreeInstance]
404641 [系统] [@ ClassDestroy]
4D313E [UnitSam.pas] [TSam.Destroy] [297]
4042BF [系统] [TObject。免费]
4149ED [SysUtils] [FreeAndNil]
4D9C0A [UnitAsmJob.pas] [UnitAsmJob] [TAsmJob.Destroy] [180]

我在IDE中启用了所有调试选项,包括范围检查。此外,FastMM4设置为超级攻击性调试模式。没有FastMM或调试器之外的程序运行得很好 - 但是我知道这并不意味着错误不再存在了。实际上它可能(可能)工作了一年以上,直到我安装了FastMM。






编辑:



感谢大家。不,我感觉到我有一个很好的方向。



程序的结构更复杂,我只提供了保持原始帖子的骨干。但是呢,它已经变得更大了:)
所以,这些TSam对象被用来从磁盘加载数据。每个对象中的一个文件。他们也在做一些处理和数据验证。对于这些TSam中的每一个,我还有一个图形对象,在屏幕上显示(图形化)TSam对象中包含的数据。 TStringGrid中的每一行也显示TSam中的数据,但是在文本上。



我有一个问题:如果我以较小的部分打破程序,找出错误在哪里,错误还会出现吗?或者只能在这个特定配置中出现?






回答AsmJob如何分配给TStringGrid so TStringGrid破坏了AsmJob,可以告诉我们吗?

  MyGrid = TStringGrid 
public
AsmJob :TAsmJob;
结束

然后在TForm.Create(保存网格的表单)的某个地方,我做

  MyGrid.AsmJob = AsmJob; 

在MyGrid的析构函数中我做:

  begin 
FreeAndNil(AsmJob);
继承
结束;


解决方案

此错误意味着您的代码损坏了内部内存管理器的结构。你的电话堆栈代表点,当MM检测到这个。这不是错误路径或与之相关的任何内容。在此刻之前发生实际的错误。
它可能或可能与上述类无关。



您应该尝试使用范围检查错误选项(不要忘记使Build,而不是编译)和FastMM在完全调试模式下(使用CheckHeapForCorruption,CatchUseOfFreedInterfaces和DetectMMOperationsAfterUninstall选项启用)



您还可以打开FullDebugModeScanMemoryPoolBeforeEveryOperation全局变量,几乎立即在发生问题后立即收到错误,但此选项会降低执行速度A LOT。



可能最好的选择是定期调用ScanMemoryPoolForCorruptions。把它称为一个地方。有错误?早点打电话还有错误吗?再次打电话。没有错误?您的问题位于最后一次电话之间。现在可以使用FullDebugModeScanMemoryPoolBeforeEveryOperation变量来获取精确位置。只需在这个代码区域上打开它就可以在它之后关闭。



有一个非常相似的错误:FastMM检测到一个块在被修改后被修改释放。在这种情况下,您的代码不会修改内部结构,而是修改其他内存(根本不用)(可用内存)。



BTW,您的错误不是双-自由!如果这是一个双重免费的通话,FastMM会明确告诉你(它很容易被检测,因为你正在尝试释放未使用或不存在的内存块):已经尝试释放/重新分配未分配块。


I had this nasty bug that disappeared in the past but now after quite some time it returned.

I have two TSam objects (derived from TPersistent) created and loaded into an TAsmJob object (derived from TObjectList).

At runtime, a form creates a TStringGrid and then the AsmJob which creates those two SAM objects (and load some data from disk in each of them). The AsmJob is also assigned to the grid. When the form is destroyed, the Grid takes care of the AsmJob by freeing it, which frees the TSam objects. Here is the problem: the first object is freed withot problems but the second one dies when its inherited method (in Destroy destructor) is called.

I use FreeAndNil in the entire program to free the objects. The TSam objects are not NIL!!!!! So, this is the first attempt to free the objects. Even the data inside the objects is consistent.

The backbone of the program looks like this:

**Create:**

Form -> StringGrid
     -> AsmJob -> Sam1, Sam2
StringGrid.AsmJob:= AsmJob;


**Free:**

Form -> StringGrid -> AsmJob -> Sam1, Sam2

I really don’t understand where I try to double-free or overwrite the object AFTER it has been released.


edit:

Some of the errors I got:

  • FastMM has detected an error during a free block scan operation. FastMM detected that a block has been modified after being freed.

  • FastMM has detected an error during a free block scan operation. The block header has been corrupted.

Detail:

The current thread ID is 0x19C, and the stack trace (return addresses) leading to this error is: 
402E77 [System][@FreeMem] 
4068DC [System][@DynArrayClear] 
405E2D [System][@FinalizeArray] 
405D31 [System][@FinalizeRecord] 
40432F [System][TObject.CleanupInstance] 
404272 [System][TObject.FreeInstance] 
404641 [System][@ClassDestroy] 
4D313E [UnitSam.pas][TSam.Destroy][297] 
4042BF [System][TObject.Free] 
4149ED [SysUtils][FreeAndNil] 
4D9C0A [UnitAsmJob.pas][UnitAsmJob][TAsmJob.Destroy][180]  

I have all "debug" options enabled in the IDE, including the "Range Check". Also, the FastMM4 is set to super aggressive debug mode. Without FastMM or outside of the debugger the program runs just fine - but yet I know it doesn't mean that the bug is not there anymore. Actually it worked (probably) for more than one one year, until I have installed FastMM.


edit:

Thanks to everybody. No I am feeling I am moving a bit in the good direction.

The structure of the program is more complicated I offered only the backbone to keep the original post small. But what the heck, it already got larger :) So, those TSam objects are used to load data from disk. One file in each object. They are doing also some processing and data validation. For each of these TSam I also have a graphical object that shows on the screen (graphically) the data contained in the TSam objects. Each line in the TStringGrid also show the data in TSam, but textually.

One question I have: if I break the program in smaller pieces to find out where the error is, the error will still appear? Or it is possible to appear only in this particular configuration?


Answer to "how does the AsmJob get assigned to TStringGrid so that the TStringGrid destroys the AsmJob, can you show us?"

MyGrid = TStringGrid
  public 
    AsmJob: TAsmJob; 
  end; 

then somewhere in the TForm.Create (the form that holds the Grid), I do

MyGrid.AsmJob=AsmJob; 

and in the destructor of the MyGrid I do:

begin 
  FreeAndNil(AsmJob); 
  inherited 
end;

解决方案

This error means that your code corrupted internal memory manager's structures. Your call stack represents point, when MM detected this. This is not error path or anything related to it. The actual error happens BEFORE this moment. It may or may be not related to mentioned classes.

You should try to use "Range check errors" option (don't forget to make Build, not Compile) and FastMM in full debug mode (with CheckHeapForCorruption, CatchUseOfFreedInterfaces и DetectMMOperationsAfterUninstall options enabled).

You can also turn on FullDebugModeScanMemoryPoolBeforeEveryOperation global variable, to get an error almost immediately after problem occurs, but this option slows down your execution A LOT.

Probably the best choice is call ScanMemoryPoolForCorruptions periodically. Call it in one place. Got an error? Call it sooner. Still got an error? Call it sooner again. No error? Your problem sits somewhere between those last calls. Now you can use FullDebugModeScanMemoryPoolBeforeEveryOperation variable to get precise location. Just turn it on only on this code's area and turn it off right after it.

There is a very similar error: "FastMM detected that a block has been modified after being freed". In this case your code modifies not internal structures, but other memory, which isn't used at all ("free memory").

BTW, your error is NOT double-free! If this is a double-free call, FastMM will tell you that explicitly (it is easy to detect, as you are trying to free not-used or not-existed memory block): "An attempt has been made to free/reallocate an unallocated block".

这篇关于FastMM4说“块头已被损坏”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆