Wie nutzt man Memcheck.pas ? [ gelöst ]

Rund um die LCL und andere Komponenten
Antworten
Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1629
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Wie nutzt man Memcheck.pas ? [ gelöst ]

Beitrag von corpsman »

Guten Morgen,

Ich schreibe mir gerade mein eigenes DBMS und gebe mir hierbei die totale Pointerschlacht. Ich bin zwar der guten Hoffnung auch wieder alle frei gegeben zu haben, doch sicher bin ich mir eben nicht.

Für Windows und Delphi gab es da die Memcheck.pas, doch wenn man in der liest, steht da extra das sie nur für Delphi sei. Also hab ich mal angefangen nach einer Lazarus Version zu suchen. Google sagte mir dann das Lazarus so was hat. und Tatsächlich

lazarus/components/codetools/memcheck.pas

gibt es.

Nun von der Delphi her weis ich, dass man Memcheck als 1. Unit einbinden musste und dann die Prozedur Memchk aufrufen musste. In der Lazarus Memcheck.pas gibt es die Prozedur nicht, ich hab sie aber einfach mal so eingebunden und wollte sehen was passiert. Aber außer einer AV beim Starten wo der Debugger dann in memcheck_laz.inc :

Code: Alles auswählen

procedure RunError(RunErrorNumber: word);
begin
  if ExceptOnError then begin
    // create an gdb catchable exception
    if 0=(1 div ((ord(ExceptOnError) and 1) shr 1)) then ; <-- HIER
  end;
  if HaltOnError then System.Halt(1);
  System.RunError(RunErrorNumber);
end;
stehen bleibt passiert weiter nichts. Leider gibt es kein Example welches mir den genauen Umgang mit Memcheck.pas erklärt. In der Windows Version musste man bei den Compiler Einstellungen was umändern ( Mit DEBUGG DCU's ) und dann neu Compilieren.

Nun hab ich zwar ein bischen mit den Compiler Einstellungen rum gespielt doch funktionniert hats bisher noch nicht.

Daher nun die Frage an euch, könnt ihr mir sagen wie ich Memcheck.pas nutzen kann ?

Die Windows Version war sehr Komfortabel, da hat man am Schluss einen Dialog bekommen, ob es Leaks gab, und wenn es welche tatsächlich welche gab, sprang der Debugger sogar an die Zeile in der der Speicher Allokiert wurde, und gab dann den Bericht aus...

Das hier ist mein bisheriges Testprogramm :

Code: Alles auswählen

Var
  Form1: TForm1;
  P: Pinteger = Nil;
 
Implementation
 
{ TForm1 }
 
Procedure TForm1.Button1Click(Sender: TObject);
Begin
  new(p);
End;
 
Procedure TForm1.Button2Click(Sender: TObject);
Begin
  If assigned(p) Then
    dispose(p);
  p := Nil;
End;
Und Momentan passiert natürlich nichts, wenn ich Button1 geklickt habe, und beim beenden button2 noch nicht.

Könnt ihr mir weiter helfen ?
Zuletzt geändert von corpsman am So 13. Dez 2009, 11:35, insgesamt 1-mal geändert.
--
Just try it

Hitman
Beiträge: 512
Registriert: Mo 25. Aug 2008, 18:17
OS, Lazarus, FPC: ArchLinux x86, WinVista x86-64, Lazarus 0.9.29, FPC 2.4.1
CPU-Target: x86
Wohnort: Chemnitz

Re: Wie nutzt man Memcheck.pas ?

Beitrag von Hitman »

Warum nicht einfach heaptrc nutzen? (-gh compiler parameter bzw. halt in den Compilersettings von Lazarus)

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1629
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Wie nutzt man Memcheck.pas ?

Beitrag von corpsman »

bei

Project-> compiler Options-> Linking-> Use heaptrc

hab ich nen hacken gemacht, und alles neu compiliert.

Aber wenn ich dann mein Sample ausführe , sehe ich nirgends eine Meldung oder sonst was , das ich vergessen hätte die 4 Byte für den Pointer frei zu geben...

Es gibt zwar ne Datei heap.err aber die ist leer ..
--
Just try it

Euklid
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Re: Wie nutzt man Memcheck.pas ?

Beitrag von Euklid »

Ich nutze auch die heaptrc für die oben geschilderten Probleme. Die Konsolenausgaben waren bisher immer hilfreich.
Wichtig bei der Nutzung der heaptrc ist (meines Wissens), dass sämtliche Optimierungen sowie Smartlinking deaktiviert sein muss.

Ein sehr rennomiertes Tool ist valgrind; ich weiß nicht, ob du das kennst: http://valgrind.org/" onclick="window.open(this.href);return false;

Um valgrind nutzen zu können, musst du in den Compilereinstellungen "Code für valgrind erzeugen" aktivieren.

Viele Grüße, Euklid

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1629
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Wie nutzt man Memcheck.pas ?

Beitrag von corpsman »

AHA, das die Ausgabe in der Console stattfindet, das hatte ich nun nicht berücksichtigt ;).

Da stehts dann Tatsächlich : das 4 Bytes verloren gingen, allerdings sind alle weiteren Ausgaben in keinster weise Hilfreich mir an zu zeigen woher der "leak" kommt :

Code: Alles auswählen

corpsman@corpsman2:~/Desktop/Memcheck_test$ ./project1        
[WARNING] Out of OEM specific VK codes, changing to unassigned
[WARNING] Out of unassigned VK codes, assigning $FF           
Heap dump by heaptrc unit                                     
1467 memory blocks allocated : 994108/998224                  
1466 memory blocks freed     : 994104/998216                  
1 unfreed memory blocks : 4                                   
True heap size : 262144                                       
True free heap : 262064
Should be : 262072
Call trace for block $B76DF6A0 size 4
  $0817CC84  TCONTROL__CLICK,  line 2277 of ./include/control.inc
  $081BDACF  TBUTTONCONTROL__CLICK,  line 72 of ./include/buttoncontrol.inc
  $081BE0C5  TCUSTOMBUTTON__CLICK,  line 164 of ./include/buttons.inc
  $081BE621  TBUTTON__CLICK,  line 331 of ./include/buttons.inc
  $081BD96A  TBUTTONCONTROL__WMDEFAULTCLICKED,  line 26 of ./include/buttoncontrol.inc
  $0806B83A
  $08173472  TWINCONTROL__WNDPROC,  line 5107 of ./include/wincontrol.inc
  $081F7E47  DELIVERMESSAGE,  line 111 of lclmessageglue.pas
Das heist dann, das ich nur sehen kann , obich überhaupt einen Leak erzeuge, oder eben nicht, was ja auch schon mal Cool ist, da es ja mehr ist wie ich bisher konnte ;).

das Valgrind kannte ich noch nicht werde es mir aber mal ansehen gehen ;).

Eins noch, kann man dieses Compilerswitch auch irgendwie vom Code aus setzten ?

{$GH+}

geht nicht. Und eine Automatische Konsolen Ausgabe wäre in dem Zug natürlich der Brüller.
--
Just try it

Euklid
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Re: Wie nutzt man Memcheck.pas ?

Beitrag von Euklid »

corpsman hat geschrieben:Das heist dann, das ich nur sehen kann , obich überhaupt einen Leak erzeuge, oder eben nicht, was ja auch schon mal Cool ist, da es ja mehr ist wie ich bisher konnte ;).
Die heaptrc zeigt dir einen Call trace an, aus dem in der Regel auf die Stelle im Code geschlossen werden kann. Was du da siehst ist dann ein Aufrufstack: Die oberste Zeile gibt in der Regel die Codezeile wieder, in der der Speicherbereich definiert wird, der nicht freigegeben wird.
Dafür ist es notwendig, dass in den Compilereinstellungen "Zeilennummer [...] anzeigen" aktiviert sowie "Debuggersymbole [...] entfernen" deaktiviert ist.
das Valgrind kannte ich noch nicht werde es mir aber mal ansehen gehen ;).
Valgrind ist sehr mächtig. So ein bisschen wie mit Kanonen auf Spatzen schießen. Hinsichtlich der bei meinen Programmen aufgetretenen Speicherfehlern hat die heaptrc bisher stets ihre Dienste getan und weitergeholfen.
Eins noch, kann man dieses Compilerswitch auch irgendwie vom Code aus setzten ?
Mir ist da kein Switch bekannt.

Viele Grüße, Euklid

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1629
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Wie nutzt man Memcheck.pas ?

Beitrag von corpsman »

Danke Euklid,

Das valgrind eine Mega Kanone ist, hab ich gerade auch festgestellt. Wenn das alles stimmt, dann erzeugt ein Standart Lazarus Projekt, ganz schön viele Leaks :

Code: Alles auswählen

==14630== LEAK SUMMARY:
==14630==    definitely lost: 2,336 bytes in 9 blocks
==14630==    indirectly lost: 7,112 bytes in 358 blocks
==14630==      possibly lost: 317,610 bytes in 1,354 blocks
==14630==    still reachable: 302,223 bytes in 6,581 blocks
==14630==         suppressed: 0 bytes in 0 blocks
==14630== Reachable blocks (those to which a pointer was found) are not shown.
==14630== To see them, rerun with: --leak-check=full --show-reachable=yes
Ich Denke mir wird dieses Heaptrc ebenfalls reichen.

Wo finde ich denn den hacken für Debuggersymbole nicht entfernen ?
Dateianhänge
Compiler_options.png
--
Just try it

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Re: Wie nutzt man Memcheck.pas ?

Beitrag von monta »

Wo finde ich denn den hacken für Debuggersymbole nicht entfernen ?
In deinem Bild "Strip Symbols from Excecutable" aktiviert entfernt die Debuginfos, so bleiben sie drin.

Testweise für zusätzliche Debuginfos mal das erste aktivieren.
Johannes

Euklid
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Re: Wie nutzt man Memcheck.pas ?

Beitrag von Euklid »

Im Screenshot ist es im Grunde schon richtig eingestellt.

"Strip Symbols from Executable" ist die Einstellung, die deaktiviert sein muss.

Dann müsste der Trace der heaptrc jetzt eigentlich zielführend sein....

... wenn nicht, kannst du ihn ja mal posten.

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1629
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Wie nutzt man Memcheck.pas ?

Beitrag von corpsman »

Also,

der 1. hacken hat nichts gebracht.

Und wenn ich das nun richtig lese dann schreibt er mir immer die Stelle an der die Aktuelle Prozedur, die die Allokation die nicht entfernt worden ist, erzeugt hat, auf.

Da in dem Oberen Beispiel das ein TButton.onlick war hat mir das natürlich überhaupt nichts gesagt. Ich habe die Allokation nun aber mal ausgelagert in eine extra Prozedur und dann hat er mir genau die Codezeile des Aufrufs hingeschrieben, das hilft dann natürlich, da ich nur schauen brauche welche Prozedur da aufgerufen wird. Und in der ist dann das nicht freigegebene ;)

Vielen Dank an alle beteiligten. Das erzielte Ergebnis ist zwar nicht so luxuriös wie das der Delphi Version. Reicht aber locker aus ;).
--
Just try it

Hitman
Beiträge: 512
Registriert: Mo 25. Aug 2008, 18:17
OS, Lazarus, FPC: ArchLinux x86, WinVista x86-64, Lazarus 0.9.29, FPC 2.4.1
CPU-Target: x86
Wohnort: Chemnitz

Re: Wie nutzt man Memcheck.pas ? [ gelöst ]

Beitrag von Hitman »

Also bei mir springt er auch in solche Events. Aber ich vermute, dass dein Fall derart simpel ist (eine einzelne Code-Zeile), dass dir da irgendeine Optimierung in die Quere kommt. Ich behaupte, in richtigem Code wirst du das Problem nicht haben.

Antworten