Давно я не брал в руки шашек, то есть Lazarus. В последний раз это было в тот самый момент, когда самая свежая версия Lazarus была 0.9.29. Сейчас самая актуальная версия — 2.0.9. А так как, в свете последних событий, я решил реанимировать свой старый ноутбук и, даже умудрился установить на него Debian 10.3, то очередное знакомство с Lazarus стало неизбежностью. И сегодня я попытаюсь собрать всю информацию о том, как в Lazarus искать утечки памяти. Как это сделать в Delphi я рассказывал и приводил стандартный пример, а вот тема поиска утечек памяти Lazarus для меня достаточно новая.
Пример с утечкой памяти
Для начала создадим простенький проект в Lazarus, в котором будет явная утечка памяти. В проекте будет одна форма с кнопкой:
Соответственно, клик по кнопке и будет создавать утечку памяти:
procedure TForm1.Button1Click(Sender: TObject); begin TObject.Create; end;
Естественно, что после запуска приложения, клика по кнопке и выключения приложения вы ничего не увидите — программа тихо завершит свою работу. Чтобы мы смогли узнать, что в нашем приложении присутствует утечка памяти, в Lazarus зайти в параметры проекта и включить параметр «Использовать модуль Heaptrc (проверка на наличие утечек памяти) (-gh)»:

Теперь, после завершения работы нашей программы можно будет увидеть следующую информацию об утечке памяти:
Здесь можно увидеть, что причиной утечки памяти стал код в строке 34 модуля unit1.pas — тот самый код, который приведен выше. Теперь, разобравшись с этим примером, посмотрим, что мы ещё можем сделать для поиска и анализа утечек памяти в Lazarus.
Как запретить компилировать проект, если выключена опция -gh в Lazarus?
Можно воспользоваться, например, директивами компилятора fpc и поместить в любом месте программы вот такой код:
{$IF NOT DECLARED(heaptrc)} {$ERROR You must compile this program with -gh} {$ENDIF}
Теперь, если опция -gh выключена в параметрах проекта, то проект не скомпилируется, а вы увидите в окне сообщений ошибку с текстом «You must compile this program with -gh».
Как сохранить лог heaptrc в файл?
Для того, что вывод heaptrc сохранялся в файле, необходимо открыть исходный код проекта (lpr-файла), то есть выбрать в меню «Проект — Просмотреть исходный код проекта» и добавить после begin следующий код:
SetHeapTraceOutput('heaptrace.trc');
Теперь, после завершения программы рядом с exe-файлом появится файл вывода heaptrc:
При этом, окно с выводом heaptrc по завершению программы появляться не будет.
Как просмотреть лог heaptrc в Lazarus?
В принципе, можно и в обычном блокноте, так как heaptrace.trc ни что иное, как обычный текстовый файл, но можно просмотреть этот файл и через инструмент самого Lazarus. Для этого выбираем пункт меню: «Вид — Утечки памяти и стек вызовов»:
В открывшемся окне указываем наш файл и получаем вот такой отчёт об утечках памяти в проекте:
Двойной клик по информации об утечке перенесет вас в нужную строку исходного кода. Например, я дважды кликнул по строке «$000000010002F33A line 35 of unit1.pas» и Lazarus показал это место в исходнике проекта
Утечек точно нет, а окно heaprtc всё равно показывается. Что делать?
Продемонстрировать вопрос, указанный в подзаголовке можно просто — закомментируем в нашем проекте строку:
TObject.Create;
и отключим вывод heaprtc в файл. После запуска и остановки приложения появится окно:
По информации в этом окне видно, что утечек, как таковых нет. Чтобы каждый раз не смотреть на это, а выводить сообщение только при наличии утечек памяти, в Lazarus в исходном коде проекта (lpr-файле) добавляем следующую строку:
globalSkipIfNoLeaks := true;
Теперь окно с выводом heaprtc будет появляться только тогда, когда будет обнаружена утечка памяти.
Что ещё почитать про поиск утечек памяти в Lazarus?
Если вы хотите больше узнать про heaprtc в Lazarus и FPC, то могу посоветовать следующую официальную информацию:







globalSkipIfNoLeaks — не находит такую переменную. Lazarus 1.6.