3

Delphi XE ではReportMemoryLeaksOnShutDown、アプリケーションを終了するときに常にリークを検出していました。ほとんどのプロジェクトはかなり小規模であり、通常、リークを見つけることはそれほど難しくありませんでした。

Lazarus にはそのようなオプションはありませんが、Heaptrcon と呼ばれるオプションを見つけました。詳細については、このページを参照してください: http://wiki.lazarus.freepascal.org/Profiling

Project Options > Linking で (-gh) フラグを設定しました。コードを投稿しますが、さまざまなクラスとユニットがたくさんあるため、これらのリークを修正するためにどこから始めればよいかわかりません。これは、私が取り組んだ他のどのプロジェクトよりもはるかに大きなプロジェクトです。

これはいくつかのリークのスクリーンショットです:

ここに画像の説明を入力

私のデバッグ スキルは実質的にゼロです。これまで、作成したすべてのオブジェクトまたはクラスを確認し、解放されているかどうかを確認しました。私は多くの TLists や Pointers/Objects などを扱っているため、どこからでもリークが発生している可能性があります。

どこから探し始めるかの手がかりやヒントはありますか? サイズが 16 の各ブロックのコール スタックを見ていますが、6 個あります。これは、6 個のオブジェクトが正しく破棄されていないことを意味しますか?

途方に暮れています。どこから始めればよいですか?

前もって感謝します。

4

2 に答える 2

3

本当に必要な情報は、リークした各オブジェクトに関連付けられた割り当てのスタック トレースです。それらはスクリーンショットに表示されますが、関数名ではなくアドレスとして表示されます。デバッグ情報を有効にすると、名前が表示されます。その後、Delphi で FastMM を使用する場合とまったく同じ方法で問題を追跡できます。

于 2013-09-04T13:19:34.020 に答える
2

David Heffernan が以前のコメントの 1 つで述べたように、これらのアドレスを関数名に変換する方法が必要です。

最初のステップはGenerate debugging info for GDB、何らかの理由で有効になっていないものを有効にしたことを確認することでした。次に、それらの関数名を取得しました。

アドレスをたどると、TList オブジェクトにたどり着きました。現在、私が取り組んでいるこのプロジェクトは実際には Delphi XE で開始されましたが、Lazarus に移植しています。これらのエラーは XE では検出されませんでしたが、TList オブジェクトを解放するときに次のようにしました。

var
  P: Pointer;
begin
  for P in MyList do TMyListItem(P).Free;
end;

テスト用に XE をインストールしていませんが、上記でエラーが発生しなかったことを覚えています。

また、ツリービューにオブジェクトを追加していました (これらのオブジェクトは からのポインターMyListでした)。これらを解放していませんでした。しかし、それを行った後でも、リークはまだ存在していました.

さまざまなことを何時間も試し、あきらめそうになった後、簡単なことを見逃していることに気付きました。

var
  P: Pointer;
begin
  for P in MyList do TMyListItem(P).Free;
  MyList.Free;
end;

私は Delphi でその部分を見逃しており、リークについて不平を言うことはなかったと確信していますが、Lazarus/FPC では大量の新しいリークがありました。これまでのところ、すべてのリークがなくなり (うまくいけば)、もう戻ってくることはありません。

リークを報告しているため、それほど怖くはないように見える次のリーク レポートが表示されますzero

ここに画像の説明を入力

于 2013-09-05T07:45:34.097 に答える