最新的 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;
temp := temp + format('%.2X ', [b]);
FastMM 在withformat
或处引发“内存不足”异常IntToHex
。调用堆栈导致 _USrCat、_UStrSetLength、_ReallocMem。总是在i = 27
。参数为p1
TBytes 数组的地址,长度为 128 字节,填充 41 字节( NativeUInt(@FData[0]) )。我试图将内存访问断点设置为 7FFFFE62540(地址来自 FastMM 消息“从指针地址 7FFFFE62540 开始的 256 字节的当前内存转储”),从应用程序开始跟踪这个内存块:它是空的未使用区域,直到内存块创建地址 7FFFFE62450 和地址 7FFFFE62540 由 FastMM 填充为 ptr + f0(当i = 27
)。检查此块的控制和后,FastMM 失败(在 CPU 窗口中跟踪)。我也尝试排除此日志部分,但在简单时遇到了类似的异常inherited
创建一个对象(远在此代码执行之后)。也只发生在FullDebugMode
.
最后,我尝试使用相同的选项并FastMM4Options.inc
在 32 位下构建和检查这个项目Target Platforms
- 根本没有错误。一切安好。除了我无法在 Windows 7-64 下调试它。
那么 FastMM 中是否存在代码错误或已知错误?我花了 3 天时间跟踪它,但没有其他想法该怎么做(甚至尝试更换插槽中的前 4 GB 内存,4 x 2048)。使用来自 FastMM4 的 FastMM_FullDebugMode64.dll 和 FastMM_FullDebugMode.dll。谢谢。
编辑:解决这些事情很糟糕,但似乎我为自己找到了策略(已解决,这是缺点all in one
,相同的对象作为不同的类取决于 OLE 或 Direct 模式,使用对象作为不同的类对象引起的错误)
1. 放FastMM4 在错误发生之前调用 LogAllocatedBlocksToFile(0, 0)
2. 在日志中查找最近的对象,对我来说,它是错误地址下方 300 字节附近的地址对象
3. 将数据断点放在错误地址附近的非零区域(对我来说它低于 40 美元字节)。几个断点,因为像 256 字节这样的大区域只是没有被更改触发。在这种情况下,它是最近对象的末尾(地址+日志大小)和错误地址之间的区域。
4. 分析断点上的代码。
5. 多次运行寻找要跟踪的内容,最后得到错误代码位置。在每次运行时重新启用数据断点,因为 IDE 会禁用它们。