最新の 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]);
ます。コール スタックは、_UStrCat、_UStrSetLength、_ReallocMem につながります。常に. パラメータのパラメータは、41 バイトで埋められた 128 バイト長の TBytes 配列のアドレスです ( NativeUInt(@FData[0]) )。メモリ アクセス ブレークポイントを 7FFFFE62540 に配置しようとしました (FastMM メッセージ「ポインタ アドレス 7FFFFE62540 で始まる 256 バイトの現在のメモリ ダンプのアドレス」) に、アプリケーションの開始からこのメモリ ブロックをトレースしました。アドレス 7FFFFE62450 とアドレス 7FFFFE62540 は、FastMM によって ptr + f0 として埋められます ( の場合)。このブロックのコントロール サムをチェックした後、FastMM が失敗します (CPU ウィンドウでトレース)。また、このログ部分を除外しようとしましたが、シンプルで同様の例外が発生しましたformat
IntToHex
i = 27
p1
i = 27
inherited
オブジェクトの 1 つを作成します (このコードの実行後)。の下でのみ発生し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.置くエラーが発生する直前の LogAllocatedBlocksToFile(0, 0) への FastMM4 呼び出し
2. ログで最も近いオブジェクトを見つけます。私にとっては、エラー アドレスの 300 バイト下の $300 バイト近くのアドレスでオブジェクトでした
3. エラー アドレスの近くのゼロ以外の領域にデータ ブレークポイントを配置します (私にとっては) 40 バイト近く下にありました)。256 バイトのような大きな領域が変更によってトリガーされなかったため、いくつかのブレークポイント。この場合、最も近いオブジェクトの末尾 (アドレス + ログによるサイズ) とエラーのアドレスの間の領域でした。
4. ブレークポイントでコードを分析します。
5.何を追跡するかを見つけるために数回実行し、最終的にエラーコードの位置を取得しました。IDE はデータ ブレークポイントを無効にするため、実行ごとにデータ ブレークポイントを再度有効にします。