[Gelöst] Sigsegv Error bei delay Aufruf

Für Fragen von Einsteigern und Programmieranfängern...
Okil
Beiträge: 32
Registriert: Mi 14. Aug 2019, 16:33
OS, Lazarus, FPC: Lazarus 2.0.8, FPC 3.0.4, Linux, (Windows 7)
CPU-Target: 64Bit / 32 Bit
Wohnort: Umland München

[Gelöst] Sigsegv Error bei delay Aufruf

Beitrag von Okil »

Hallo,

bei einem Programm für die Steuerung von mehreren Heizungspumpen mit dem Raspberry bekomme ich einen Sigsegv Fehler wenn ich von einem SpinEdit den Wert an die delay Procedure übergebe. Wenn ich den Wert manuell im delay eintrage, funktioniert das Programm problemlos. Zuerst dachte ich, es hängt damit zusammen, dass SpinEdit Longint liefert und delay word erwartet. In einem Testprogramm nur mit einem SpinEdit und delay funktioniert dies jedoch. Auch Typumwandlung brachte nichts.

Jetzt vermute ich, dass ich evtl. etwas bei der Übertragung sPIN := PIN falsch mache (PChar nach string [2]) und dadurch im Speicher etwas überschrieben wird. Der Wert im sPIN kommt jedoch korrekt an. Dennoch könnte es irgendwie damit zusammenzuhängen.

Hat jemand eine Idee, wo der Fehler liegen könnte?
Vielen Dank.

Code: Alles auswählen

procedure GPIOSwitchRelais (PIN : pChar; PINOn : boolean);
var
  fileDesc: integer;
  sPIN : string [2];

begin
  sPIN := PIN;
  delay (Config.SpinEditSwitchDelay.Value);

  if PINOn then
  begin
    { Relais An (Low aktiv) }

    try
      fileDesc := fpopen('/sys/class/gpio/gpio'+sPIN+'/value', O_WrOnly);
      gReturnCode := fpwrite(fileDesc, PIN_OFF[0], 1);
    finally
      gReturnCode1 := fpclose(fileDesc);
    end;
  end
  else
  begin
    { Relais aus }
    try
      fileDesc := fpopen('/sys/class/gpio/gpio'+sPIN+'/value', O_WrOnly);
      gReturnCode := fpwrite(fileDesc, PIN_ON[0], 1);
    finally
      gReturnCode1 := fpclose(fileDesc);
    end;
  end;
end;   
Zuletzt geändert von Okil am Fr 17. Jul 2020, 19:50, insgesamt 1-mal geändert.

Mathias
Beiträge: 6910
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Sigsegv Error bei delay Aufruf

Beitrag von Mathias »

Jetzt vermute ich, dass ich evtl. etwas bei der Übertragung sPIN := PIN falsch mache (PChar nach string [2]) und dadurch im Speicher etwas überschrieben wird. Der Wert im sPIN kommt jedoch korrekt an.
Brauchst du zwingend einen Pchar ?
Mache mal den String länger als 2, oder nimm gar einen normalen String.
Oder mache als Versuch aus spin eine Konstante.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Okil
Beiträge: 32
Registriert: Mi 14. Aug 2019, 16:33
OS, Lazarus, FPC: Lazarus 2.0.8, FPC 3.0.4, Linux, (Windows 7)
CPU-Target: 64Bit / 32 Bit
Wohnort: Umland München

Re: Sigsegv Error bei delay Aufruf

Beitrag von Okil »

Ich habe das Beispiel von

https://wiki.freepascal.org/Lazarus_on_Raspberry_Pi/de

etwas modifiziert, da 10 Pumpen.

Und dort wird bei den Activate und Close Prozeduren ein pChar verwendet

const
PIN_17: PChar = '17';
.
.

gReturnCode := fpwrite(fileDesc, PIN_17[0], 2);

Aber Du hast Recht. Zumindest in der Umschaltroutine des Relais wäre die pChar Variable nicht erforderlich. Nur für die Activate und Close Prozeduren. Wollte nicht für 10 Pumpen separate PChar und String Konstanten definieren, sondern in allen Prozeduren die gleiche Konstante durchreichen.

Mit zusätzlich

const
sPIN_17 : string [2] = '17'

werde ich es mal testen, auch wenn es nicht so sauber ist.

Mit string Typ hatte ich schon probiert. Gleiche Fehlermeldung.

Okil
Beiträge: 32
Registriert: Mi 14. Aug 2019, 16:33
OS, Lazarus, FPC: Lazarus 2.0.8, FPC 3.0.4, Linux, (Windows 7)
CPU-Target: 64Bit / 32 Bit
Wohnort: Umland München

Re: Sigsegv Error bei delay Aufruf

Beitrag von Okil »

Habe das jetzt mal testweise geändert mit separaten Konstanten.
Bricht immer noch mit SIGSEGV Fehler beim delay ab. Typecasting mit word bringt auch nichts

Code: Alles auswählen

procedure GPIOSwitchRelais (sPIN : string2; PIN : pChar; PINOn : boolean);
var
  fileDesc: integer;
 
begin
  delay (Config.SpinEditSwitchDelay.Value);  //Hier Abbruch mit SIGSEGV

  if PINOn then
  begin
    { Relais An (Low aktiv) }

    try
      fileDesc := fpopen('/sys/class/gpio/gpio'+sPIN+'/value', O_WrOnly);
      gReturnCode := fpwrite(fileDesc, PIN_OFF[0], 1);
    finally
      gReturnCode1 := fpclose(fileDesc);
    end;
  end
  else
  begin
    { Relais aus }
    try
      fileDesc := fpopen('/sys/class/gpio/gpio'+sPIN+'/value', O_WrOnly);
      gReturnCode := fpwrite(fileDesc, PIN_ON[0], 1);
    finally
      gReturnCode1 := fpclose(fileDesc);
    end;
  end;
end;   
Die Init Procedure funktioniert jedoch merkwürdigerweise.

Code: Alles auswählen

procedure GPIOInit (PIN : PChar);
.
.
gReturnCode := fpwrite(fileDesc, PIN[0], 2)
delay (Config.SpinEditInitDelay.Value);  //Hier kein Abbruch

.
.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Sigsegv Error bei delay Aufruf

Beitrag von Winni »

Hi1

Merkwürdig. Aber ein alter Kalauere aus meinen frühen Delphi-Zeiten:

SpinEdit spinnt manchmal. Daher der Name.

Aber mach doch bitte mal folgenden Test, damit man sieht, ob es das implizite casting ist:

Code: Alles auswählen

delay (word(Config.SpinEditSwitchDelay.Value));
Winni

Okil
Beiträge: 32
Registriert: Mi 14. Aug 2019, 16:33
OS, Lazarus, FPC: Lazarus 2.0.8, FPC 3.0.4, Linux, (Windows 7)
CPU-Target: 64Bit / 32 Bit
Wohnort: Umland München

Re: Sigsegv Error bei delay Aufruf

Beitrag von Okil »

delay (word(Config.SpinEditSwitchDelay.Value));

Das hatte ich auch schon gleich am Anfang getestet. Gleiche Fehlermeldung.

Wenn ich über die Variable mit der Maus fahre, steht dort "Type TSPINEDIT has no component named VALUE. ". Zeigt er allerdings auch an allen anderen Stellen mit delay Aufrufen an, obwohl dort das Delay funktioniert.

Ich könnte jetzt einfach schreiben delay (200). Das geht z.B. Aber da später bestimmte Relais in Abhängigkeit von anderen Relais mit Verzögerung geschaltet werden, werde ich früher oder später wieder bei dem Problem landen.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Sigsegv Error bei delay Aufruf

Beitrag von Winni »

Hallo!

1) SpinEdit löschen. speichern, SpinEdit wieder rauf aufs Formular, umbenennen, Verbindungen zu den Events wiederherstellen .

2.) Falls das .nix nützt:

Code: Alles auswählen

i := SpinEditSwitchDelay.Value;
showMessage (IntToStr(i));
delay (i);
Mal sehen, wo er jetzt crasht.

Winni

Okil
Beiträge: 32
Registriert: Mi 14. Aug 2019, 16:33
OS, Lazarus, FPC: Lazarus 2.0.8, FPC 3.0.4, Linux, (Windows 7)
CPU-Target: 64Bit / 32 Bit
Wohnort: Umland München

Re: Sigsegv Error bei delay Aufruf

Beitrag von Okil »

Winni hat geschrieben: Di 14. Jul 2020, 22:25 Hallo!

1) SpinEdit löschen. speichern, SpinEdit wieder rauf aufs Formular, umbenennen, Verbindungen zu den Events wiederherstellen .

2.) Falls das .nix nützt:

Code: Alles auswählen

i := SpinEditSwitchDelay.Value;
showMessage (IntToStr(i));
delay (i);
Mal sehen, wo er jetzt crasht.

Winni
So, habe ich gemacht. Zur Sicherheit Rechner neu gestartet.

zu 1) Gleiche Fehlermeldung beim delay trotz SpinEdit löschen, Name ändern und verschieben des Aufrufs ans Ende innerhalb der Procedur
zu 2) Gleiche Fehlermeldung, jedoch jetzt bei dem
i := SpinEditSwitchDelay.Value;

Mathias
Beiträge: 6910
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Sigsegv Error bei delay Aufruf

Beitrag von Mathias »

Was passiert, wen du ein normales Edit nimmst ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Okil
Beiträge: 32
Registriert: Mi 14. Aug 2019, 16:33
OS, Lazarus, FPC: Lazarus 2.0.8, FPC 3.0.4, Linux, (Windows 7)
CPU-Target: 64Bit / 32 Bit
Wohnort: Umland München

Re: Sigsegv Error bei delay Aufruf

Beitrag von Okil »

Mathias hat geschrieben: Di 14. Jul 2020, 23:00 Was passiert, wen du ein normales Edit nimmst ?
Da scheint wohl ein größers Problem vorzuliegen. Schon

var s : string;

begin
s := Edit1.Text
end;

bringt den gleichen Fehler.

Auch muß ich revidieren, dass die anderen SpinEdits funktionieren. Von 7 beliebig an verschiednen Stellen im Code und auf der Form positionierten bringen 3 die Fehlermeldung.

Das Programm ist noch recht jungfreulich und hat zum Testen der Relais und SSRs nur einige ToggleBoxen, Timer, RatioButtons etc.; jedoch noch keine Eingabefelder. Daher ist mir dies bisher nicht aufgefallen. Die Relais und Thermoschalter etc. funktionieren jedoch alle auch im Dauerbetrieb problemlos.

(Raspberry 4, Lazarus ARM Version 2.0.8 und FPC 3.0.4)

Ein kleines separates Testprogramm mit mehren delays, SpinEdits und normalen Edits funktioniert ohne Fehler.

Mathias
Beiträge: 6910
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Sigsegv Error bei delay Aufruf

Beitrag von Mathias »

Was passiert, wen du das ganze gpio Zeugs ausklammerst ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1639
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Sigsegv Error bei delay Aufruf

Beitrag von fliegermichl »

Kann es evtl sein, dass dein Formular nicht der Variablen Config zugewiesen ist? das erscheint mir hier am plausibelsten.

Deine Routine ist ja keine Methode des Formulares.

Okil
Beiträge: 32
Registriert: Mi 14. Aug 2019, 16:33
OS, Lazarus, FPC: Lazarus 2.0.8, FPC 3.0.4, Linux, (Windows 7)
CPU-Target: 64Bit / 32 Bit
Wohnort: Umland München

Re: Sigsegv Error bei delay Aufruf

Beitrag von Okil »

fliegermichl hat geschrieben: Mi 15. Jul 2020, 09:22 Kann es evtl sein, dass dein Formular nicht der Variablen Config zugewiesen ist? das erscheint mir hier am plausibelsten.

Deine Routine ist ja keine Methode des Formulares.
Ja, ich habe langsam auch die Vermutung, dass es an den beiden Formularen liegt. Ich lagere bei all meinen Programmen immer die individuellen Einstellungen auf ein eigenes Formular aus, hier "Config". Die Werte werden in einer XML Datei gespeichert und Im Hauptformular "Heizungssteuerung" über einen Menüpunkt bei Bedarf modifiziert. Das funktionierte immer problemlos. Allerdings hatte ich bisher nie die Funktion OnActivate im Hauptformular benutzt, weil immer irgendeine Benutzeraktion die einzelnen Funktionen auslöste.

Bei diesem Programm müssen die Relais jedoch bereits beim Start initialisiert und auf vordefinierte Werte gesetzt werden. Dafür verwende ich verschiedene Einstellungen von dem Config Formular und nutze die OnActivate Funktion des Hauptformulars.

Ich vermute daher, das beim OnActivate der Form "Heizungssteuerung" noch nicht korrekt alle Werte der "Config" Form zur Verfügung stehen. Seltsamerweise funktioniert es jedoch bei etwa 70 % der Einstellungen.

Bin gerade nicht zu Hause, werde das mal testen, wenn ich zurück bin.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6770
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Sigsegv Error bei delay Aufruf

Beitrag von af0815 »

Es kann auch ein Grund sein, das man nicht im richtigen Kontext (Hauptthread) ist. Dann gibt es sehr kryptische Fehler.

Das passiert gerne wenn man einen Callback verwendet, der dann irgenwo eine Routine aufruft die mit einem visuellen Element in Verbindung ist. Dann kann (muss leider nicht) es krachen.

Wenn es schon nötig ist, dann es mit einer globalen Variable machen, die beim Laden der Konfig (oder ändern durch ein GUI Element) befüllt wird und keine direkte Verbindung zu der GUI unterhält.

Grundlegend sollte mal alles was GPIO ist, so kapseln, das es Threadsicher wäre.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Okil
Beiträge: 32
Registriert: Mi 14. Aug 2019, 16:33
OS, Lazarus, FPC: Lazarus 2.0.8, FPC 3.0.4, Linux, (Windows 7)
CPU-Target: 64Bit / 32 Bit
Wohnort: Umland München

Re: Sigsegv Error bei delay Aufruf

Beitrag von Okil »

Also, irgendwie stehe ich jetzt auf dem Schlauch. In allen Programmen greife ich so von Form1 auf Elemente der Form2 zu. Das funktioniert immer. Auch in diesem Testprogramm.

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Unit2;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var s : string;

begin
  s := form2.Edit1.Text;
  Label1.Caption:= s;
end;

end.
                  
Nur in dem aktuellen Heizungsprogramm funktioniert das nicht. Wenn ich von unit1 (Form1) auf ein Edit oder SpinEdit Wert von Unit2 (Form2) zugreife, kommt (fast) immer der SIGSEGV Fehler. Selbst wenn ich dies nicht bei OnActivate mache, sondern die Initialsierung über einen Button auslöse.

Wenn ich die Form2 mit meinen SpinEdit Werten beim Start einmal öffne und schließe, dann funktioniert im Anschluß alles problemlos und die Werte werden sauber übernommen.

Die Werte von Form2 sind also aus irgend einem Grund nicht verfügbar, bevor die Form2 nicht mindestens einmal mit ShowModal aufgerufen wurde.

Wenn ich die SpinEdits von Form2 auf Form1 verschiebe geht es auch. Ist aber keine Lösung, da ich auf Grund der Fülle an Einstellmöglichkeiten diese auf eine eigene Form packen möchte. Auskommentieren der GPIO Funktionen bringt auch nichts.

Antworten