Question

Latest FastMM4 4.991, XE2, was trying to solve memory leaks and got this error under FullDebugMode + LogErrorsToFile settings. Error

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]
...

Code is quite simple and was used in several projects without any errors

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 raises "Out of memory" exception at temp := temp + format('%.2X ', [b]); with format or IntToHex. Call stack leads to _UStrCat, _UStrSetLength, _ReallocMem. Always at i = 27. Parameter for p1 is address of TBytes array 128 bytes length filled with 41 bytes ( NativeUInt(@FData[0]) ). I've tried to put memory access breakpoint to 7FFFFE62540 (address from FastMM message "Current memory dump of 256 bytes starting at pointer address 7FFFFE62540"), traced this memory block from application start: it is empty unused area up to memory block creation at address 7FFFFE62450 and address 7FFFFE62540 filled as ptr + f0 by FastMM (when i = 27). After checking this block for control sum FastMM fails (traced in CPU Window). Also I've tried to exclude this log part but got similar exception at simple inherited Create of one of objects (far after this code execution). Also happens only under FullDebugMode.

Finally I tried to build and check this project with same options and FastMM4Options.inc under 32-bit Target Platforms - there is no errors at all. Everything is fine. Except I can't debug it under Windows 7-64.

So is there any errors in code or known bugs in FastMM? I've spent 3 days tracing it and have no other ideas what to do (even tried to replace first 4 GB memory in slots, 4 x 2048). Used FastMM_FullDebugMode64.dll and FastMM_FullDebugMode.dll from FastMM4. Thanks.

edit: It is awful to solve such things but it seems I found strategy for myself (solved, it was drawbacks of all in one, same object as different classes depending on OLE or Direct mode, error caused by using object as different class object)
1. Put FastMM4 call to LogAllocatedBlocksToFile(0, 0) right before error should happen
2. Find nearest object in log, for me it was object by address near $300 bytes below error's address
3. Put Data breakpoints to nonzero areas near your error address (for me it was near $40 bytes below). Several breakpoints because big areas like 256 bytes just was not triggered by changes. In this case it was area between the end of nearest object (address + size by log) and error's address.
4. Analyze code on breakpoints.
5. Several runs to find what to track and finally got error code position. Reenable Data breakpoints on each run, because IDE disables them.

Was it helpful?

Solution

The symptoms you describe are those of a heap corruption. You say the error occurs here:

temp := temp + format('%.2X ', [b]);

Well, both temp and b are local variables, and Format is known to work correctly. Therefore the only conclusion I would contemplate is that you have, before this code runs, corrupted the heap.

Stop looking at FastMM and focus on your code. Make a simple SSCCE and if you can't solve it from there, we should be able to.

OTHER TIPS

If you're using FastMM4, try setting FastMM4.FullDebugModeScanMemoryPoolBeforeEveryOperation := true; It'll run a full corruption check before every memory operation. This can really slow things down, but it also makes it much easier to find where something is going wrong: when it reports an error, then at someplace between the last memory operation and the current code, something got corrupted. This makes your search a lot easier.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top