Difference between revisions of "heaptrc/ru"

From Free Pascal wiki
Jump to navigationJump to search
Line 54: Line 54:
 
Heaptrc не работает, если вы используете его с FPC 3.0.4 в Linux и ваша программа вызывает функцию <syntaxhighlight lang="text" inline>system.get_cmdline</syntaxhighlight>, и в этом случае вы получите в конце программы много сообщений об ошибках EAccessViolation. Это похоже на ошибку, например в FPC 3.2.0-beta rev 43824 эта проблема не возникает.
 
Heaptrc не работает, если вы используете его с FPC 3.0.4 в Linux и ваша программа вызывает функцию <syntaxhighlight lang="text" inline>system.get_cmdline</syntaxhighlight>, и в этом случае вы получите в конце программы много сообщений об ошибках EAccessViolation. Это похоже на ошибку, например в FPC 3.2.0-beta rev 43824 эта проблема не возникает.
  
=== Using heaptrc in Lazarus ===
+
=== Использование heaptrc в Lazarus ===
To enable this in your Lazarus project:
+
Чтобы включить это в вашем проекте Lazarus:
# Go to ''Project Options/Linking'' and
+
# Идем в раздел Project Options/Compiler Options/Debugging (Параметры проекта/Параметры компилятора/Отладка) и
# in the Debugging section enable ''Use Heaptrc unit (check for mem-leaks) (-gh)''
+
# в разделе Other debugging info (Прочая отладочная информация) включаем ''Use Heaptrc unit (check for mem-leaks) (-gh)'' (Использовать модуль Heaptrc (проверка на наличие утечек памяти) (-gh))
  
You can test for the presence of <syntaxhighlight lang="pascal" inline>heaptrc</syntaxhighlight> in a similar manner as in the above example by testing for the presence of <syntaxhighlight lang="pascal" inline>useHeapTrace</syntaxhighlight> in your project.lpr file.
+
Вы можете проверить наличие <syntaxhighlight lang="pascal" inline>heaptrc</syntaxhighlight> таким же образом, как в приведенном выше примере, проверив наличие <syntaxhighlight lang="pascal" inline>useHeapTrace</syntaxhighlight> в вашем файле project.lpr.
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
{$if declared(useHeapTrace)}
 
{$if declared(useHeapTrace)}
// ... do something
+
// ... что-то делаем
 
 
// test if active
+
// проверяем активность
 
if useHeapTrace then
 
if useHeapTrace then
 
begin
 
begin

Revision as of 22:15, 2 January 2022

English (en) русский (ru)

heaptrc - это модуль, который можно использовать для отладки выделения и освобождения блоков памяти. Он отслеживает вызовы getMem/freeMem и, неявно, операторы new/dispose.

Warning-icon.png

Предупреждение: Не добавляйте модуль heaptrc вручную. Модуль heaptrc необходимо загрузить до lineinfo, и только компилятор может это сделать. Heaptrc также является диспетчером памяти, поэтому не пытайтесь использовать какой-либо диспетчер памяти, включая сам heaptrc, в разделе uses, поскольку это может привести к повреждению памяти и ложным результатам. В этом разделе содержится примечание с примером кода для универсальной обработки такого случая.

When a program using heaptrc ends, heaptrc can write out the total memory used and a list of allocated but not freed blocks to a file. When run in the console (*nix or Windows), heaptrc will print this output to screen unless otherwise instructed. In Lazarus GUI programs on Windows, the output will appear in numerous small dialog boxes, which may be very unpractical, although you can redirect output to file.

Когда программа, использующая heaptrc, завершается, heaptrc может записать общий объем используемой памяти и список выделенных, но не освобожденных блоков в файл. При запуске в консоли (*nix или Windows) heaptrc выводит эту информацию на экран, если не указано иное. В программах Lazarus с графическим интерфейсом пользователя в Windows вывод будет отображаться во множестве небольших диалоговых окон, что может быть очень непрактичным, хотя вы можете перенаправить вывод в файл.

Standard output of heaptrc on Windows (despite of the title there is no error in the application)

В * nix (включая BSD, Linux и macOS) по умолчанию для программ с графическим интерфейсом ничего не отображается (прим.перев.: для вывода в консоль под *nix необходимо подключить окно в разделе View/Debug Window/Console In/Output).

console output win.png

См. Leakview для получения подробной информации о том, как эффективно использовать heaptrc.

Использование

Использование heaptrc в FPC

Добавьте параметр -gh в командную строку компиляции или в fpc.cfg.

fpc -gh helloworld.pas

или обычно в сочетании с информацией о строке:

fpc -glh helloworld.pas

Это добавит heaptrc неявно, как скрытый первый модуль раздела uses программы.

Вы можете проверить в коде, активен ли heaptrc, проверив глобальную константу useHeapTrace на наличие heaptrc и ее статус следующим образом:

program possiblyHeaptraced(input, output, stdErr);
begin
	{$if declared(useHeapTrace)}
		writeLn('Heaptrc is used.');
                // отчеты heaptrc могут быть отключены при связывании в ... true или false
		writeLn('Heaptrc is active: ', useHeaptrace); 
                // впоследствии вы можете протестировать/задать любые параметры отчетов heaptrc
	{$else}
		writeLn('No trace of heaptrc.');
	{$endIf}
end.

Обратите внимание, что {$if declared(useHeapTrace)} работает только в программе, а не в модуле.

Heaptrc не работает, если вы используете его с FPC 3.0.4 в Linux и ваша программа вызывает функцию system.get_cmdline, и в этом случае вы получите в конце программы много сообщений об ошибках EAccessViolation. Это похоже на ошибку, например в FPC 3.2.0-beta rev 43824 эта проблема не возникает.

Использование heaptrc в Lazarus

Чтобы включить это в вашем проекте Lazarus:

  1. Идем в раздел Project Options/Compiler Options/Debugging (Параметры проекта/Параметры компилятора/Отладка) и
  2. в разделе Other debugging info (Прочая отладочная информация) включаем Use Heaptrc unit (check for mem-leaks) (-gh) (Использовать модуль Heaptrc (проверка на наличие утечек памяти) (-gh))

Вы можете проверить наличие heaptrc таким же образом, как в приведенном выше примере, проверив наличие useHeapTrace в вашем файле project.lpr.

{$if declared(useHeapTrace)}
	// ... что-то делаем
	
	// проверяем активность
	if useHeapTrace then
	begin
		// ...
	end;
{$endIf}

Show report only on leak

If you want to show heaptrc report dialog only if there were leaks in your application, then put this assignment somewhere in your main project source file:

{$if declared(useHeapTrace)}
	globalSkipIfNoLeaks := true; // supported as of debugger version 3.2.0
{$endIf}

Programmatically disable report

If you want to disable report from your code then you can directly manipulate useHeapTrace constant at program startup:

useHeapTrace := false;

This will in effect change the behavior to a normal memory manager.

Continue execution even on heap error

If you want your application to continue execution even in case of a heap error then manipulate haltOnError constant at program startup:

haltOnError := false;

Redirect report to file

If you want to redirect leak report to file then add this to beginning of you main project file:

setHeapTraceOutput('trace.log'); // supported as of debugger version 3.2.0

Why heaptrc should not be added to the uses clause manually

You should never add heaptrc manually in a normal program, because the heaptrc unit needs to be loaded before lineinfo for debugging to work properly.

Decoding dwarf debugging info efficiently requires a working heap manager and this means that heaptrc needs to be loaded before the the dwarf line info decoding unit which is loaded by -gl, so heaptrc cannot be used explicitly.

Only the compiler itself can insert the unit in its proper place as a hidden first unit in the uses clause. Adding the unit by hand can cause all kind of unwanted side effects. E.g. crashes, reported lineinfo is not reliable and not all leaks can reliably be reported.

This has always been the case, but is only properly documented from FPC version 3.0.2. So if you still see heaptrc in your uses clause, remove it! for debugging and reporting to work properly.

Light bulb  Примечание: If your program is designed to use an alternative memory manager, you can adapt your program's uses clause like so:

program alternativeMemoryManager(input, output, stdErr);
{$mode objFPC}
uses
	// This will conditionally switch in a memory manager
	// based on the presence of heaptrc
	{$if not declared(useHeapTrace)}
		cMem,
	{$endIf}
	sysUtils, classes; // the latter two are just to test.

begin
	{$if declared(useHeapTrace)}
		writeLn('Heaptrc is used.', ' Heaptrc is active: ', useHeaptrace);
	{$else}
		writeLn('No trace of heaptrc.');
	{$endIf}
end.

In the above example the conditional in the uses clause makes sure that the cmem memory manager is only compiled in if the heaptrc option is not used.

See also