最新的FastMM4 4.991,XE2,试图解决内存泄漏,并在FullDebugMode + LogErrorsToFile设置下得到了这个错误。错误
The current thread ID is 0x7C4, and the stack trace (return addresses) leading to this error is:
41B914 [FastMM4][CheckFreeBlockUnmodified$qqrrp29Fastmm4.TFullDebugBlockHeaderui23Fastmm4.TBlockOperation]
41B996 [FastMM4][DebugGetMem$qqri]
41BD1F [FastMM4][DebugReallocMem$qqrrpvi]
40615D [System.pas][System][@ReallocMem$qqrrpvi][3524]
40CF62 [System.pas][System][@UStrSetLength$qqrr20System.UnicodeStringi][24163]
40D057 [System.pas][System][@UStrCat$qqrr20System.UnicodeStringrx20System.UnicodeString][24290]
8127D6 [LogHandler.pas][LogHandler][AddCustomLog$qqruiuii][160]
...代码非常简单,并在几个项目中使用,没有任何错误。
procedure AddCustomLog(p1, p2: NativeUInt; MsgType: integer);
const
MSG_LEN = 200;
var
ErrorString: array [0 .. MSG_LEN] of Char;
i: integer;
temp: string;
descr: UTF8String;
b: byte;
pb: PByte;
begin
case MsgType of
...
BUFFER_LOG: begin
temp := 'len = ' + IntToStr(p2) + ' buf : ' + sLineBreak;
descr := '';
pb := PByte(p1);
for i := 0 to p2 - 1 do begin
b := pb^;
// if i = 27 then LogAllocatedBlocksToFile(0, 0);
temp := temp + format('%.2X ', [b]); //IntToHex(b, 2) + ' ';
if ((b >= $20) and (b < $80)) or (b >= $C0) then
descr := descr + UTF8Encode(AnsiChar(b))
else
descr := descr + '.';
if (i mod $10) = $F then begin
temp := temp + ' | ' + UTF8ToString(descr) + sLineBreak;
descr := '';
end;
inc(pb);
end;
if length(temp) > 0 then
AddToLog(temp + ' | ' + UTF8ToString(descr));
end;
end;
end;FastMM在temp := temp + format('%.2X ', [b]);中用format或IntToHex引发“内存不足”异常。调用堆栈导致_UStrCat、_UStrSetLength、_ReallocMem。总是在i = 27。p1的参数是TBytes数组的地址,长度为128个字节,填充41个字节( NativeUInt(@FData) )。我尝试将内存访问断点放置到7FFFFE62540 (来自FastMM消息的地址“从指针地址7FFFFE62540开始的256个字节的当前内存转储”),从应用程序开始跟踪这个内存块:它是空的未使用区域,直到地址7FFFFE62450和地址7FFFFE62540被FastMM (i = 27时)填充为ptr + f0。检查此块以确定控制和后,FastMM失败(在CPU窗口中跟踪)。此外,我试图排除这个日志部分,但在简单的inherited创建对象(在执行代码后很远)获得了类似的异常。也只有在FullDebugMode下才会发生。
最后,我尝试用相同的选项和32位FastMM4Options.inc下的Target Platforms构建和检查这个项目--根本没有错误。百事大吉。但我不能在Windows 7-64下调试它。
那么,FastMM中是否存在代码错误或已知的错误呢?我花了3天的时间追踪它,没有其他的想法做什么(甚至试图替换前4GB内存插槽,4x2048)。使用FastMM_FullDebugMode64.dll和来自FastMM4的FastMM_FullDebugMode.dll。谢谢。
编辑:解决这些问题很糟糕,但我似乎为自己找到了策略(解决了all in one的缺点,根据OLE或直接模式,同一对象与不同的类相同,使用对象作为不同的类对象所造成的错误)
发布于 2014-03-12 19:12:03
你描述的症状是堆腐败的症状。您说错误发生在这里:
temp := temp + format('%.2X ', [b]);好的,temp和b都是局部变量,而Format是正确工作的。因此,我要考虑的唯一结论是,在运行此代码之前,堆已经损坏。
停止查看FastMM,专注于您的代码。做一个简单的SSCCE,如果你不能从那里解决它,我们应该能够。
发布于 2014-03-12 20:01:28
如果您正在使用FastMM4,请尝试在每次内存操作之前设置FastMM4.FullDebugModeScanMemoryPoolBeforeEveryOperation := true; --它将运行一个完整的损坏检查。这可以让事情慢下来,但它也使我们更容易找到出问题的地方:当它报告一个错误时,然后在最后一个内存操作和当前代码之间的某个地方,一些东西被破坏了。这样你的搜索就容易多了。
https://stackoverflow.com/questions/22361339
复制相似问题