Linux: OnUtf8KeyPress() > Abort > EXE hängt [Bug]

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

Linux: OnUtf8KeyPress() > Abort > EXE hängt [Bug]

Beitrag von MmVisual »

Hallo,

Einer hatte mir gemeldet dass meine EXE unter Linux sich aufhängt. Nun habe ich das untersucht und festgestellt dass wenn man in einem bestimmten Event ein "Abort" schreibt, dass dann sich die EXE tatsächlich komplett weg hängt.

In dem Beispielprojekt wird das "FormUTF8KeyPress()" Event ausgewertet, und wer da ein "a" drückt für "Abort", der lässt dann die EXE aufhängen.

Das Problem gibt es nur unter Linux.
TestLinuxUtf8KeyPress.zip
(105.44 KiB) 104-mal heruntergeladen
(Debian 64 Bit, falls es wichtig ist, Lazarus V2.2.0.rc3, geladen mit FpcUpDeluxe)

Bugreport schreiben?

Der Code:

Code: Alles auswählen

procedure TForm1.FormUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin
  If UTF8Key = 'a' Then
    UTF8Key := #0;
  If UTF8Key = #0 Then
    Abort;
end;
VG Markus
EleLa - Elektronik Lagerverwaltung - www.elela.de


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

Re: Linux: OnUtf8KeyPress() > Abort > EXE hängt [Bug]

Beitrag von MmVisual »

1) Im FormUTF8KeyPress() werden nicht nur Tastensignale von einer echten Tastatur empfangen sondern auch emulierte Tasten Signale von einem 2D Codescanner (der eine USB Tastatur simuliert). Immer wenn das Start-Zeichen erkannt wird sollen alle Zeichen vom Scanner eingelesen werden, bis zur Ende Kennung vom Scanner (Start und Ende sind programmierbar). Während dem Scan darf das Tastensignal keine weitere Aktionen auslösen, da es ein reiner Scan Code ist. -> Abort

2) Im FormUTF8KeyPress() werden alle möglichen Tasten-Kurzbefehle (Ctrl+xxxx) abgefragt und ausgewertet. Immer wenn so ein Tastenbefehl erkannt und ausgewertet wird, darf dieser nicht mehr an die unterliegende Komponente weiter geleitet werden. Wenn in so einem Fall einfach nur
UTF8Key := #0;
gemacht wird dann bimmelt die EXE bei jedem Tastencode. Dieses gepiepe nervt irgendwann und die einzige Abhilfe (unter Windows) war ein Abort, damit war dann (endlich) ruhe.

3) Seit ich dann endlich die Windows EXE zum schweigen gebracht hatte ... stürzt nun die Linux EXE als Dank dafür ab :cry:

Das Problem ist dass der gleiche Code unter Windows <> Linux anders funktioniert.
Abort ist ja dafür da dass die Bearbeitungskette eines Ereignisses einfach unterbrochen wird und mit der nächsten Message in der Message Queue weiter machen sollte. Ich nutze Abort zwar ungern, jedoch manchmal ist es einfacher ein Abort zu nehmen.
EleLa - Elektronik Lagerverwaltung - www.elela.de

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

Re: Linux: OnUtf8KeyPress() > Abort > EXE hängt [Bug]

Beitrag von wp_xyz »

Keine Ahnung, ob das mit dem Abort in Ordnung ist oder nicht. Aber ich würde das anders angehen: UTF8Char ist kein char, sondern ein String, daher kann man im Fehlerfall einen Leerstring zurückgeben, statt einer #0. Und in der Tat, wenn ich in den Quellcode gucke (von TWinControl.DoUTF8KeyPress), dann finde ich dort den Abschnitt:

Code: Alles auswählen

  if not (csNoStdEvents in ControlStyle) then
  begin
    UTF8KeyPress(UTF8Key);   // das löst das OnUTF8KeyPress-Ereignis aus
    if UTF8Key = '' then Exit;
  end; 
Wenn der Eventhandler also einen Leerstring als UTF8Key zurückgibt, dann wird die DoUTF8KeyPress unverichteter Dinge verlassen, und du brauchst das Abort gar nicht. Zumindest konnte ich nun unter Ubuntu beobachten, dass dein Testprogramm die Eingabe des 'a' blockiert ohne abzustürzen.

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

Re: Linux: OnUtf8KeyPress() > Abort > EXE hängt [Bug]

Beitrag von theo »

Braucht es den Workaround überhaupt auf Linux?
Ich höre nichts bimmeln.

Code: Alles auswählen

{$IFDEF WINDOWS} 
    ...
{$ENDIF}

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

Re: Linux: OnUtf8KeyPress() > Abort > EXE hängt [Bug]

Beitrag von MmVisual »

Hallo,

Wenn bei Linux nichts bimmelt, dann ist es noch ein zweiter Bug wo die EXE zwischen Linux <> Windows anders arbeitet.

Ich habe im Demo-Quellcode nun ein Häkchen rein gesetzt mit dem man das "Abort" aktivieren kann wenn es gesetzt ist. Ohne Abort bimelt die EXE mit "a" oder "Ctrl+a".

Code: Alles auswählen

procedure TForm1.FormUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin
  If UTF8Key[1] In ['a', #1] Then
    UTF8Key := #0;
  If (UTF8Key = #0) And CheckBox1.Checked Then
    Abort;
end;
TestLinuxUtf8KeyPress.zip
(105.56 KiB) 94-mal heruntergeladen
Ich habe bei mir erst einmal den Workaround für Linux eingebaut, damit der Komplett Hänger erst einmal "umgangen" ist.

Code: Alles auswählen

{$IFNDEF UNIX} 
    ...
{$ENDIF}
VG Markus
EleLa - Elektronik Lagerverwaltung - www.elela.de

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

Re: Linux: OnUtf8KeyPress() > Abort > EXE hängt [Bug]

Beitrag von theo »

MmVisual hat geschrieben:
So 12. Dez 2021, 07:52
Wenn bei Linux nichts bimmelt, dann ist es noch ein zweiter Bug wo die EXE zwischen Linux <> Windows anders arbeitet.
Nicht alles was bei Linux anders ist als bei Windows, ist gleich ein Lazarus Bug.

Hast du den Beitrag von wp_xyz auch gesehen?
https://lazarusforum.de/viewtopic.php?p=125308#p125308

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

Re: Linux: OnUtf8KeyPress() > Abort > EXE hängt [Bug]

Beitrag von MmVisual »

Mit

Code: Alles auswählen

UTF8Key := '';
Bimmelt die Win Exe auch nicht mehr, auch ohne Abort.
Das Abort braucht es somit auch nicht mehr.
Dass der Typ TUTF8Char auch leer sein kann brachte mich etwas durcheinander. Der Typ Char kann ja auch nicht leer sein,
Ähnlich wie ein Integer Wert, der kann 0 sein jedoch nicht NIL, also dass da keine Zahl drin steht, auch nicht 0.

Thx für die Hilfe ... dennoch sollte ein Abort; in FormUTF8KeyPress() erlaubt sein.

VG Markus
EleLa - Elektronik Lagerverwaltung - www.elela.de

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

Re: Linux: OnUtf8KeyPress() > Abort > EXE hängt [Bug]

Beitrag von wp_xyz »

MmVisual hat geschrieben:
So 12. Dez 2021, 10:31
Dass der Typ TUTF8Char auch leer sein kann brachte mich etwas durcheinander. Der Typ Char kann ja auch nicht leer sein.
Dieser Schluss beruht auf der Anwesenheit von "Char" in dem Typ-Namen. Aber TUTF8Char ist kein char, sondern ein String! Denn ein UTF8-"Zeichen" (CodePoint) kann aus 1-4 bytes bestehen - genau das ist ein String. Mache einen Ctrl-Click auf "TUTF8Char", und du siehst die entsprechende Deklaration im Quelltext:

Code: Alles auswählen

type
  TUTF8Char = String[7];  // UTF-8 character is at most 6 bytes plus a #0  // wp: warum 6 und nicht 4? 
Deshalb kann ein UTF8Char trotzdem ein LeerString' sein. Überzeugt?

Zurück zu Abort: Es sieht so aus, als ob diese stille Exception unter Linux nicht fehlerfrei arbeitet. Aber dann sollte das Problem nicht nur bei OnUTF8KeyPress auftreten, sondern - um bei diesem Beispiel zu bleiben - auch im normalen OnKeyDown/OnKeyPress o.ä. Hast du das beobachtet?

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

Re: Linux: OnUtf8KeyPress() > Abort > EXE hängt [Bug]

Beitrag von MmVisual »

>> OnKeyDown/OnKeyPress o.ä. Hast du das beobachtet?

Das "Abort" hatte ich erst im November eingebaut, damit es nicht beept. Im Juli hatte ich das von OnKeyPress auf UTF8 umgebaut und da war das Abort noch nicht drin, in OnKeyDown/Up nutze ich kein Abort.

Abort gibt es noch bei TZQuery.BeforePost, wenn man wegen einem Eingabefehler noch nicht den Post ausführen darf, da funktioniert Abort unter Linux.
Da ich selbst kaum Linux nutze ist mir da noch nichts aufgefallen, ich bin da abhängig von den Linux Usern, die mein Programm nutzen.

VG Markus
EleLa - Elektronik Lagerverwaltung - www.elela.de

PascalDragon
Beiträge: 825
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Linux: OnUtf8KeyPress() > Abort > EXE hängt [Bug]

Beitrag von PascalDragon »

MmVisual hat geschrieben:
Sa 11. Dez 2021, 21:54
Das Problem ist dass der gleiche Code unter Windows <> Linux anders funktioniert.
Abort ist ja dafür da dass die Bearbeitungskette eines Ereignisses einfach unterbrochen wird und mit der nächsten Message in der Message Queue weiter machen sollte. Ich nutze Abort zwar ungern, jedoch manchmal ist es einfacher ein Abort zu nehmen.
Nein, Abort ist letztlich nichts anderes als eine Exception. Und wenn der aufrufende Code nicht darauf vorbereitet ist damit umzugehen (in diesem Fall eben der Qt/GTK+ Teil der LCL), dann knallt es eben (wie auch immer sich das "Knallen" nun äußert).
FPC Compiler Entwickler

Antworten