sporadischer GetMem Fehler

Antworten
siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

sporadischer GetMem Fehler

Beitrag von siro »

Hallo liebe Gemeinde,

ich bekomme leider in meiner Software immer wieder mal einen Fehler:
SIGSEV Fehler Exception-Klasse >>External<<
wobei das Assemblerfenster jedesmal irgendwie bei ..GetMem... steht.

System: Windows-7 64 Bit, Lazarus: V1.64

Kurz zur Software:
Eine serielle Kommunikation mit einem Messgerät sowie der Anzeige von Messdaten in "Echtzeit" 1 Millisekundentakt.

Der Fehler tritt sehr willkürlich auf. Also manchmal erst nach einigen Stunden
und manchmal schon nach ein paar Minuten. Das macht das Auffinden natürlich sehr schwer und lässt sich leider auch nicht provozieren. Zumindest weis ich noch nicht wie.

In meiner Software selbst benutze ich lediglich einmal GetMem im Construktor für den Messwertspeicher.
Dieser ist aber statisch und bleibt während der gesamten Laufzeit erhalten. Er wird auch nicht vergrößert oder verkleinert, er hat eine feste Größe.

Das Programm besteht eigentlich nur aus ein paar Scrollbars und Tasten.
Aber, dazu kommen ein paar sehr spezielle, eigene Komponenten für Timer und serielle Schnittstelle, welche von meiner Seite aus, jedoch kein GetMem benutzen.
Was die Windows Api oder die FTDI/Silabs Treiber machen, weiss ich natürlich nicht. Der Fehler könnte theoretisch also auch dort her rühren.

Wenn Lazarus aber den Fehler erkennt und das Assemblerfenster öffnen kann, dann vermute ich den Fehler eher nicht in den seriellen Treibern oder Windows API.
Die kennen sicher nicht die Funktion GetMem von Lazarus. Das ist aber nur eine Vermutung von mir.

Jetzt bleibt mir also zunächst die Frage, wer ruft denn zur Laufzeit die Funktion GetMem auf ? Kann ich das irgendwie ermitteln ?

TForm,TComponent,TCustomControl,TCustomPanel,TCustomLabel,TScrollBar,TLabel,
TButton,TTimer

Ein TTimer ruft alle 100ms "Invalidate" für mein Kurvenfenster auf.
In "Caption" zeige ich dann noch die benötigte Bildaufbauzeit an.
Sie liegt bei rund 50ms, je nach Größe des Fensters.

Schwieriges Problem, ich weiss, aber vielleicht hat jemand eine Idee, wie ich der Sache weiter auf den Grund gehen kann.
Meistens funktioniert es ja, aber das ist NICHT mein Stil :wink:

Danke Euch schonmal im voraus.
Siro
Dateianhänge
E_02.jpg
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: sporadischer GetMem Fehler

Beitrag von mse »

Der erste Schritt ist das Programm mit Heaptrace zu kompilieren -> -gh als Compiler Parameter.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: sporadischer GetMem Fehler

Beitrag von siro »

Okay, ich danke Dir, das habe ich jetzt so eingestellt in der IDE.

Nun warte ich auf den Fehler :)
Dateianhänge
HeapTrace.jpg
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: sporadischer GetMem Fehler

Beitrag von mse »

getmem() wird z.B. von jeder String Allokation aufgerufen (setlength(), Schreibzugriff auf Zeichen, zusammensetzen...).
Auch create() ruft getmem() auf. Der Effekt den du schilderst kann z.B. von falschen Addressen in Pointern ausgelöst werden, z.B. wenn du versehentlich auf Speicher ausserhalb deines reservierten Blockes in die Datenstruktur des Memorycontrollers schreibst. Spätere Aufrufe von getmem() laufen dann schief.
Wie sieht denn im Fehlerfall der stacktrace aus?

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: sporadischer GetMem Fehler

Beitrag von siro »

Hallo mse,
wenn man drauf wartet kommt der Fehler natürlich nicht....
ich habe aber eben, "dank deiner Hilfe" mit dem Zusatzparameter, nun sogar eine Meldung beim regulären verlassen meines Programms ein Fehler/Fenster bekommen.

Da wird anscheinend der Speicher von "TextSpace" innerhalb meiner anderen Komponenten nicht freigegeben. So sieht das zumindest für mich aus.
Ich untersuche es grad und werde das mal ändern.

Mit dem Stracktrace kenn ich mich leider noch nicht aus, hab den auch noch nicht gefunden in der IDE.

Aber erstmal SUPI Dank für deine Info

HeapTrace_2.jpg


Das Heapproblem ist jetzt gelöst, ob es mein Problemverursacher war, wird sich in den nächsten Tagen zeigen.


ich hatte tatsächlich 21 Speicherlöcher, weil ich 21 Tasten habe. Ich schäme mir, hab ich nämlich selbst verursacht.... :oops:
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: sporadischer GetMem Fehler

Beitrag von mse »

siro hat geschrieben:Da wird anscheinend der Speicher von "TextSpace" innerhalb meiner anderen Komponenten nicht freigegeben.

Das Speicherleck sollte zu keiner Exception führen, es sei denn, der gesamte Speicher wurde aufgebraucht.
Mit dem Stracktrace kenn ich mich leider noch nicht aus, hab den auch noch nicht gefunden in der IDE.

Suche nach "Stack Window" oder so.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: sporadischer GetMem Fehler

Beitrag von wp_xyz »

Ich nehme an, dein Programm läuft in der IDE, wenn die Exception kommt.

Um auch in die verwendeten Packages zu gelangen, gehe zu "Projekt-Optionen" / "Hinzufügungen und Beeinflussungen" > "Hinzufügen" > "Benutzerdefinierte Option". Klicke in die Zeile "Gespeichert in der Projektsitzung"> "Custom" und schreibe in die erscheinende Eingabezeile "-gw2" (ohne Anführungsstriche).

Übersetze dein Programm (dauert etwas länger, weil nun alle Module mit Dwarf2-Debuginformationen neu übersetzt werden.

Lasse das Programm laufen, bis die Exception kommt und das Programm mit der Exception-Meldung anhält. Klicke die Meldung weg. Öffne "Ansicht" > "Debugger" > "Aufrufstack" und du siehst welche Routinen zum Zeitpunkt der Exception aufgerufen worden sind. Wenn du das oben mit dem -gw2 gemacht hast, siehst du auch für alle verwendeten Packages die aktuellen Zeilennummern. Die Liste ist von oben nach unten zu lesen: die Routine, die den Crash verursacht hat, steht oben, die Routine in der Zeile darunter hat diese aufgerufen, diese wiederrum wurde von der nächsten Zeile aufgerufen, etc. Ein Doppelklick auf einer Zeile öffnet den Quellcode an der betreffenden Stelle. Wenn in der Spalte Funktion Fragezeichen stehen und keine Zeilennummer angegeben ist, liegt für die betreffende Stelle keine Debug-Information vor - wahrscheinlich handelt es sich um eine FPC-Unit, die von dem -gw2-Verfahren nicht erfasst wird.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: sporadischer GetMem Fehler

Beitrag von siro »

Einen schönen guten Morgen,

ersteinmal wieder VIELEN DANK an wp_xyz
Du gibts Dir wirklich sehr viel Mühe mit detailierten Informationen.
Sowas muss auch mal erwähnt und gelobt werden.

Ich werde deine Anweisung mal durcharbeiten. Wie ich sehe gibt es ja "ungeheure" Möglichkeiten
zum Debuggen der Software. Je mehr ich von Lazarus kennenlerne umso begeisterter bin ich.

Nach meiner Beseitigung des Heapfehlers, läuft mein Programm seit gestern, also jetzt 16 Stunden
ohne Probleme. Ich werd das noch weiter beobachten. Eigentlich müsste ich dann den Heapfehler wieder
einbauen um zu klären ob die Execptions dann wieder auftreten.

Die zusätzliche Option -gw2 werde ich am Wochenende probieren.
Von dem dwarf Format hatte ich schonmal von gehört, jedoch in Verbindung mit einem C-Compiler.
Dann scheint es also ein kompatibles sprachunabhängiges Format zu sein.
und das "Aufrufstack" Fenster habe ich natürlich inzwischen auch gefunden.

Es geht voran und auch nochmal vielen Dank an "mse" Die Heapüberwachung ist eine unverzichtbare Hilfe.

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: sporadischer GetMem Fehler

Beitrag von mse »

siro hat geschrieben:Nach meiner Beseitigung des Heapfehlers, läuft mein Programm seit gestern, also jetzt 16 Stunden
ohne Probleme. Ich werd das noch weiter beobachten. Eigentlich müsste ich dann den Heapfehler wieder
einbauen um zu klären ob die Execptions dann wieder auftreten.

Vor allem musst du überprüfen, ob es ohne "-gh" auch läuft. "-gh" sollte nur für Test- und Debugzwecke verwendet werden, da es die Performance vermindert und mehr Speicher braucht. Normalerweise treten die Fehler mit "-gh" früher auf als ohne, aber es kann auch einmal umgekehrt sein. Bei Speicherfehlern weiss man nie...

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: sporadischer GetMem Fehler

Beitrag von siro »

Ich habe das Programm wieder ohne -gh compiliert und ich habe wieder meinen Exception:

Der Fehler trat jetzt wieder 2 mal auf und jedesmal habe ich einen identischen Aufrufstack:

AufrufStack_02.jpg


Ich wundere mich über den Aufruf von "waveOutGetNumDevs"
das ist eine Funktion aus MMSystem von Windows.
Uses MMSystem benötige ich für meine eigene Timerkomponente.
Die Funktion waveOutGetNumDevs rufe ich aber niemals auf. Zudem würde sie vermutlich nur einmal benöigt werden beim Initialisieren.
Jetzt bin ich aber erstaunt..... :shock: Warum wird die zur Laufzeit aufgerufen, das ist ja merkwürdig.

Aber wie dem auch sei, der Verursacher könnte auch ein bis zwei Aufrufe später erfolgt sein, wenn ich das richtig interpretiere.

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: sporadischer GetMem Fehler

Beitrag von mse »

gdb kann den Stack nicht richtig abwickeln. Probiere mal das Projekt ohne Optimierung und mit Debuginfo neu zu bauen (-B -O- -gl). Möglicherweise nützt es nichts, da das Problem in einer Windows-Funktion aufzutreten scheint und da hat gdb meistens Mühe.
Ich wundere mich über den Aufruf von "waveOutGetNumDevs"
das ist eine Funktion aus MMSystem von Windows.
Uses MMSystem benötige ich für meine eigene Timerkomponente.
Die Funktion waveOutGetNumDevs rufe ich aber niemals auf. Zudem würde sie vermutlich nur einmal benöigt werden beim Initialisieren.

Dann liegt das Problem vielleicht in dem MMtimer-Interface deiner Timer-Komponente. Andererseits ist die Angabe von "waveOutGetNumDevs" im Stacktrace vielleicht falsch.
Edit: sysgetmem_fixed ist doch eine FPC Funktion, warum wird die von waveOutGetNumDevs aufgerufen?

Es wird dir vermutlich nicht weiterhelfen, aber die MSEgui TTimer Komponente hätte eine Mikrosekunden Auflösung und einen Jitter von typisch einigen Mikrosekunden auf Linux und einer Millisekunde auf Windows, falls das Flag "to_highres" gesetzt ist. Auf Windows wird dabei ebenfalls das MMtimer-System benutzt.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: sporadischer GetMem Fehler

Beitrag von siro »

Hab nochmals vielen Dank mse,
ich probiere das auch nochmal mit den genannten Optionen.
Aber das kann gut sein, dass es mit dem Timer von Windows MMSystem zusammenhängt. Würd mich nicht wundern..... :wink:
"Echtzeit" auf dem Windows hab ich eh langsam abgelegt. Das System ist einfach "vernuddelt"
Die zeitrelevanten Teile hab ich wieder auf meinem Embedded Zielsystem.
So brauche ich die 1ms auch nicht mehr so dringend und nicht so genau.
Für ein Refresh des Kurvenfensters reichen auch 50ms....
Vielleicht schmeiss ich den Timer mal raus und nehme den "normalen" TTimer.

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: sporadischer GetMem Fehler

Beitrag von Timm Thaler »

siro hat geschrieben:"Echtzeit" auf dem Windows hab ich eh langsam abgelegt. Das System ist einfach "vernuddelt"


Ähm ja, was erwartest Du? Das ist nunmal ein Multitasking-System.

Echtzeit geht schon, dazu muss man aber die Priorität seines Prozesses erhöhen. Und das sollte man tunlichst nur für kurze Zeiträume machen, sonst denkt Windows das Programm sei abgestürzt und schiesst es ab.

Ansonsten, wenn man wirklich dauerhaft Echtzeit braucht, nimmt man externe Hardware oder einen Mikrocontroller. Sonst kann Dir jedes Starten von Firefox oder Gimp erstmal ein paar Sekunden Pause bescheren.

Antworten