Strings mit länge über 255 Zeichen?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
MmVisual
Beiträge: 1639
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4.4 FPC 3.2.2)
CPU-Target: 32/64Bit

Strings mit länge über 255 Zeichen?

Beitrag von MmVisual »

Meine EXE (Win32) stürzt ab und zu undefiniert ab oder bleibt hängen. Woher das kommt kann ich nicht nachvollziehen.

Kann es sein, dass der FPC Compiler beim Zusammenbau von String die maximale Länge von 255 Bytes nicht berücksichtigt und dann den undefinierten Absturz verursacht?

FPC V2.2.3
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
theo
Beiträge: 11313
Registriert: Mo 11. Sep 2006, 19:01

Re: Strings mit länge über 255 Zeichen?

Beitrag von theo »

Eher nein. Erstens haben die Strings mit der unter Lazarus normalen Einstellung {$H+} keine fixe Länge, und zweitens würde das wohl auch mit ShortStrings nicht passieren.

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: Strings mit länge über 255 Zeichen?

Beitrag von Christian »

Den Fehler würd ich erstmal in meinem code suchen, hab sowas noch nie nachweislich von fpc/lazarus aus erlebt.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

MmVisual
Beiträge: 1639
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4.4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Strings mit länge über 255 Zeichen?

Beitrag von MmVisual »

Also so genau reproduzierbar ist der Absturz nicht. Ich habe eine Software geschrieben, die über serielle Schnittstelle Daten austauscht, dazu hab e ich SYNASER in einen TThread gekapselt, somit gibt es keine Hänger in der Bedienung.

Wenn ein anderer Dialog geöffnet wird, der ein SW-Update des Microcontrollers durchführt, dann kommt es ab und zu vor, (bei jedem dritten mal) dass sich meine EXE erst aufhängt und später dann ganz verschwindet, ohne irgend eine Meldung.

Ich habe auch in "Application.OnError" abgefangen und logge alles in eine Datei. Jeder Funktionsaufruf wird gespeichert und bei einem OnError Event kann ich die Aufrufhirarchie sehen.

Aber bei diesem Hänger steht nichts im Log.

Nun weiß ich nicht wo ich anstzen soll um das in Griff zu bekommen.

Um die einzelnen seriellen Telegramme ordentlich in der richtigen Reihenfolge zu versenden hab ich eine TStringList verwendet, die wird abgesichert beschrieben und gelesen.

Code: Alles auswählen

Constructor TThreadSer.Create;
Begin
   thSerTerminated := False;
   Inherited Create(False);
   FreeOnTerminate := True;
   fData := '';
   FWork := 0;
	lstSend := TStringList.Create;
	Evt := TEvent.Create(Nil, True, False, '');
	Evt.Release;
End;
 
Procedure TThreadSer.SendString(s: String);
Begin
	If Assigned(lstSend) And Assigned (Evt) Then
	Begin
		Evt.Acquire;
		lstSend.Add(s);
		Evt.Release;
	End;
End;
 
// Im Thread Execute:
.....
			If lstSend.Count > 0 Then // Senden von Bytes auf die serielle Schnittstelle
			Begin
				Evt.Acquire;
				While lstSend.Count > 0 Do
				Begin
					Ser.SendString(lstSend[0]);
					lstSend.Delete(0);
				End;
				Evt.Release;
			End Else Sleep(10);
....
Oder ist "TEvent" das falsche um das Threadsicher zu machen?
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
theo
Beiträge: 11313
Registriert: Mo 11. Sep 2006, 19:01

Re: Strings mit länge über 255 Zeichen?

Beitrag von theo »

Ich nehme da immer TCriticalsection. Globale Variable halten, am besten gleich im Initialization instantiieren.

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: Strings mit länge über 255 Zeichen?

Beitrag von Christian »

Also auch wenn du eine Criticalsection verwendest vor und nach dem lstSend.Add(s). ist das nicht synchron zum hauptthread ist klar das das ganze crasht. Synchronize hilft...
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Benutzeravatar
theo
Beiträge: 11313
Registriert: Mo 11. Sep 2006, 19:01

Re: Strings mit länge über 255 Zeichen?

Beitrag von theo »

Ich merke soeben: Ich versteh den Code gar nicht.
Jeder Thread baut sich seine eigene StringList. Da musst du gar nicht absichern.
Oder greift noch ein anderer Thread darauf zu? Sehe ich aber nicht im Code.

MmVisual
Beiträge: 1639
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4.4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Strings mit länge über 255 Zeichen?

Beitrag von MmVisual »

Also "TThreadSer.SendString()" wird von der Appliaktion aufgerufen, z.B. Useranfragen, oder auch mal viele Daten beim FW-Update, dann Paketweise über einen Timer.
Im "TThreadSer.SendString()" wird die Liste lstSend.Add(s); beschrieben.

Dann im eigentlichen Thread.Execute() wird die gleiche Liste mit "lstSend[0]" abgefragt und der bearbeitete Datensatz mit "lstSend.Delete(0);" gelöscht.
Nur "If lstSend.Count > 0 Then" greift ohne Sicherheitsabfrage auf die Liste zu, aber das ist nur ein Lesen eines integers, ich denke dass sollten die Threads verkraften. Die gelesenen Daten des UARTs werden natürlich mit Synchronize der Applikation übergeben.

Ich baue das mal um auf "TCriticalsection" und werde dann schnell sehen obs besser läuft. Ich geb morgen Bescheid.
Es gibt nur einen Thread, den für die serielle Bearbeitung (COM-Port/SynaSer).

Vielen Dank für eure Unterstützung!
EleLa - Elektronik Lagerverwaltung - www.elela.de

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Strings mit länge über 255 Zeichen?

Beitrag von mschnell »

Hat jetzt nichts mit dem Absturz-Problem zu tun, aber...

Den Thread mit nur 10 mSek sleep pollen zu lassen klaut Rechenzeit, die auch sinnvoll eingesetzt werden kann.

Kannst Du nicht mit TEvent.Waitfor im Thread warten und das Event mit TEvent.SetEvent im anderen Thread auslösen ?

-Michael

MmVisual
Beiträge: 1639
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4.4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Strings mit länge über 255 Zeichen?

Beitrag von MmVisual »

Ich muss doch das SetEvent gar nicht ausführen, wenn ich mit WaitFor nur z.B. 10ms warte, dann kommt WaitFor doch nach 10 ms zurück, wegen Timeout. Oder hab ich da auch was falsch verstanden?
In jedem Fall ist dieser Code besser als Sleep(). Auch beim Beenden der Applikation kann ich das Event setzen, dann beendet sich der Thread schneller.
EleLa - Elektronik Lagerverwaltung - www.elela.de

MmVisual
Beiträge: 1639
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4.4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Strings mit länge über 255 Zeichen?

Beitrag von MmVisual »

Wenn ich die TCriticalsection mit Acquire aufrufe, dann bleibt der dort stecken und die Anwendung hängt fest.

Code: Alles auswählen

Constructor TThreadSer.Create;
Begin
   thSerTerminated := False;
   Inherited Create(False);
   FreeOnTerminate := True;
   fData := '';
   FWork := 0;
	lstSend := TStringList.Create;
	Evt := TEvent.Create(Nil, True, False, '');
	Evt.Release;
   Sect := TCriticalSection.Create;
   Sect.Release;  // <<<<< Wird zu beginn aufgerufen.
End; 
 
Procedure TThreadSer.SendString(s: String);
Begin
	If Assigned(lstSend) And Assigned(Sect) And Assigned(Evt) Then
	Begin
		Sect.Acquire;   // <<<< Letzte Zeile die ausgeführt wird, dann bleibt alles hängen.
		lstSend.Add(s);
		Sect.Release;
		Evt.SetEvent;
	End;
End;
Andere Zeilen mit "Sect.xxxxx" werden nicht aufgerufen, ich hab überall einen Breakpoint gesetzt.
Muss ich noch irgend etwas anderes initialisieren?
EleLa - Elektronik Lagerverwaltung - www.elela.de

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Strings mit länge über 255 Zeichen?

Beitrag von mschnell »

MmVisual hat geschrieben: wenn ich mit WaitFor nur z.B. 10ms warte, dann kommt WaitFor doch nach 10 ms zurück, wegen Timeout.
Warum soll Waitfor denn nur 10 mSek warten ???? Wenn nix zu tun ist kann der Thread doch inaktiv bleiben bis der andere Thread ihm eine Aufgabe zuteilt und mit SetEvent weckt.

-Michael

MmVisual
Beiträge: 1639
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4.4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Strings mit länge über 255 Zeichen?

Beitrag von MmVisual »

Der Thread macht ja noch mehr, er liest Daten asynchron von der seriellen Schnittstelle und schaut da zyklisch nach.
EleLa - Elektronik Lagerverwaltung - www.elela.de

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Strings mit länge über 255 Zeichen?

Beitrag von mschnell »

MmVisual hat geschrieben:Der Thread macht ja noch mehr, er liest Daten asynchron von der seriellen Schnittstelle und schaut da zyklisch nach.
Auch ganz schlecht. Wenn von der seriellen Schnittstelle gelesen wird, geht das z.B. mit einem Blocking read. Den kann man in einem eigenen Thread machen, der im read wartet und dann, wenn Daten angekommen sind (ein Byte oder ein erkannter Block), sollte dieser Thread der Arbeits-Thread aufwecken. Dadurch kann man ineffizientes Polling vermeiden.

Es gibt Komponenten, die so etwas machen. Ich habe früher (mit Delphi) 'mal Async-Pro verwendet, das genau das tut. Ich weiß nicht wie SynaSer arbeitet, Ich hoffe aber ähnlich.

-Michael

MmVisual
Beiträge: 1639
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4.4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: Strings mit länge über 255 Zeichen?

Beitrag von MmVisual »

Ich hatte das Write vorher in der Appliaktion, also was geschrieben wenn es nötig war. Dann kam es zu Zugriffsverletzungen zwischen Read und Write, da unterschiedliche Threads den gleichen Handle nutzen.
Die Idee hatte ich auch schon, geht aber nicht mit Synaser.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Antworten