Apakah ada cara untuk mengetahui secara terprogram apakah blok memori tertentu tidak dibebaskan oleh FastMM?

103

Saya mencoba mendeteksi jika sebuah blok memori tidak dibebaskan. Tentu saja, manajer memberitahu saya dengan kotak dialog atau file log, tetapi bagaimana jika saya ingin menyimpan hasil dalam database? Misalnya saya ingin memiliki dalam tabel database nama rutinitas yang dialokasikan blok tertentu.

Setelah membaca dokumentasi FastMM saya tahu bahwa sejak versi 4.98 kami memiliki kemungkinan untuk diberi tahu oleh manajer tentang alokasi memori, kebebasan dan realokasi saat terjadi. Misalnya OnDebugFreeMemFinishperistiwa yang lewat kepada kita PFullDebugBlockHeaderyang berisi informasi yang berguna. Ada satu hal yang PFullDebugBlockHeaderhilang - informasi jika blok yang diberikan dibebaskan oleh aplikasi.

Kecuali OnDebugFreeMemFinishdipanggil hanya untuk blok yang tidak dibebaskan? Ini yang tidak saya ketahui dan ingin saya ketahui.

Masalahnya adalah bahwa bahkan mengikuti OnDebugFreeMemFinishacara saya tidak dapat mengetahui apakah blok itu dibebaskan atau tidak.

Berikut ini contohnya:

program MemLeakTest;

{$APPTYPE CONSOLE}

uses
  FastMM4, ExceptionLog, SysUtils;


procedure MemFreeEvent(APHeaderFreedBlock: PFullDebugBlockHeader; AResult: Integer);
begin
//This is executed at the end, but how should I know that this block should be freed
//by application? Unless this is executed ONLY for not freed blocks.
end;

procedure Leak;
var
  MyObject: TObject;
begin
  MyObject := TObject.Create;
end;

begin
  OnDebugFreeMemFinish := MemFreeEvent;
  Leak;
end.

Apa yang saya lewatkan adalah panggilan baliknya seperti:

procedure OnMemoryLeak(APointer: PFullDebugBlockHeader);

Setelah menjelajahi sumber FastMM saya melihat ada prosedur:

procedure LogMemoryLeakOrAllocatedBlock(APointer: PFullDebugBlockHeader; IsALeak: Boolean);

mana yang bisa dikesampingkan, tapi mungkin ada cara yang lebih mudah?

Wodzu
sumber
7
Saya selalu mengerti bahwa FastMM hanya dapat membuat pemeriksaan ini sebagai tindakan SANGAT TERAKHIR yang harus dilakukan program - menurut definisi - jadi pada saat FastMM membuat laporannya, kode Anda telah selesai. Untuk mendapatkan solusi parsial, Anda selalu dapat melihat di sumbernya untuk mengetahui bagaimana memori yang dialokasikan ditandai.
Brian Frost
6
Dilaporkan sebagai kebocoran yang diharapkan? Apakah Anda mendaftarkannya seperti yang diharapkan. Anda juga tidak dapat memutuskan bahwa memori bocor hingga dimatikan, kecuali jika Anda memberikan logika kompleks yang memahami masa aktif yang diharapkan.
David Heffernan
6
Jika OnDebugFreeMemFinishdipanggil berarti blok tersebut telah dibebaskan. Tidak ada OnMemoryLeakacara. Tidak akan pernah ada acara seperti itu. Apa yang dilakukan FastMM adalah, saat dimatikan, menentukan bahwa setiap blok yang belum dibebaskan pasti bocor. Itu tidak dapat mendeteksi kebocoran lebih awal dari itu.
David Heffernan
12
Setiap kali FastMM memberi tahu saya bahwa ada kebocoran memori, saya mematikan alat dan segera memperbaikinya. Jika Anda tidak melakukannya maka Anda akan kesulitan untuk mereproduksi kebocoran. Jika Anda benar-benar ingin masuk ke database maka Anda harus melihat fungsi CheckBlocksOnShutdown. Titik ekstensi potensial lainnya adalah AppendEventLogtetapi Anda harus memodifikasi sumber FastMM yang saya curigai.
David Heffernan
12
Erm, ambil saja file tersebut, parse dan taruh di DB?
Tony Hopkinson

Jawaban:

2

Bahkan jika penangan seperti itu ada, itu akan hampir tidak berguna, karena semuanya, termasuk DB akan dimatikan pada saat FastMM melaporkan kebocoran.

Jadi, saya sarankan Anda untuk menghidupkan LogErrorsToFilebersama dengan FullDebugModepersyaratan dalam FastMM4Options.inc. Ini akan memberi Anda file teks dengan kebocoran, yang nantinya dapat Anda parsing dan dimasukkan ke dalam DB.

Serhii Kheilyk
sumber