Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Threads und stack overflow bei Hardware am USB (https://www.delphipraxis.net/200073-threads-und-stack-overflow-bei-hardware-am-usb.html)

yogie 17. Mär 2019 06:45

Threads und stack overflow bei Hardware am USB
 
Hallo zusammen,
gleich zu Anfang: ich erwarte nicht dass mein Problem gelöst wird, es geht mir nur um eventuelle Tipps zum weiteren Vorgehen.

Folgende Situation
- ich verwende Delphi 6
- von 48 analogen Eingängen sollen Spannungen erfasst und aufgezeichnet werden
- es kommen 3 Interfaces der Fa. PICOTech (ADC-24) mit je 16 Kanälen zum Einsatz
- die Interfaces sind über USB (mit einem Hub) mit dem PC verbunden
- PICOTech stellt eine DLL zur Verfügung, mit der DLL können die handles der Interfaces abgefragt werden
- die Abfrage von je 16 Werten (ein Interface) dauert relativ lange (ca. 0,8 sec)
- in einer vom mir erstellten Thread-Klasse werden im Execute zyklisch 16 Werte eines Interface abfragt und in einem A/B Puffer ablegt
- Über die Thread-Sicherheit der DLL kann ich nichts sagen
- ich erstelle drei Instanzen der Thread-Klasse und versorge sie mit dem handle
- im Hauptprogramm läuft ein Timer der zyklisch die Puffer abfragt und die Werte anzeigt.
- das Hauptprogramm läuft ca. 3 Stunden und bricht dann mit einem Stack-Overflow ab. Dieser Effekt ist auf verschiedenen PCs mit versch. Windows-Versionen nachvollziebar.
- die Thread-Klasse war zunächst recht „naiv“ programmiert, dann habe ich mir überlegt, dass USB als eine gemeinsame Resurce geschützt werden sollte. Ich übergebe jetzt im Construtor allen drei Threads eine globale critical section, die ich vor der Verwendung des USB-Busses setze (enter) und nach der Abfrage der Werte wieder zurücksetze (leave). Das hat leider nichts gebracht,
- Den Zugriff auf den Puffer habe ich nicht geschützt, da vom Hauptprogramm nur gelesen wird, da bin ich mir schon unsicher ob das ok ist.
- die Wahrscheinlickeit für den stack overflow scheint zu steigen, wenn ich den Zyklus des Timers im Hauptprogramm verkürze. Eigentlich sind 0,5 s aussreichend, bei 100 ms kommt der overflow schon nach 30 Minten

Ich vermute der Stack-Overflow ist ein Folgefehler, habe aber keine Idee wie ich da weiterkomme. Trotz Wochenende bin ich für jeden Tipp dankbar.

Rollo62 17. Mär 2019 07:33

AW: Threads und stack overflow bei Hardware am USB
 
Meinst du mit Buffer ein Array im Stack ?
Könnte es einfach ein Speicherüberlauf sein ?
Evtl. sollte man über die Datenstruktur nachdenken, Queue vielleicht.

TurboMagic 17. Mär 2019 08:20

AW: Threads und stack overflow bei Hardware am USB
 
Als Datenstruktur käme evtl. auch ein Ringpuffer in Betracht.

Die Frage ist auch, welche Stelle genau den Stacküberlauf auslöst.
Mittels MadExcept oder Eurekalog könnte man im Absturzfall einen
Stacktrace bekommen, der einem das evtl. zeigt.

Eine kostenlose, aber nicht ganz so schöne Stacktrace Variante
findet man in der JEDI JCL.

Evtl. könnte man auch mal auf ein neueres Delphi wechseln, da hat
sich auch beim Multithreading usw. einiges getan und wenn man solche
Drittanbieter Bibliotheken braucht, tut man sich mit neueren Versionen
auch leichter, da die Unterstützung für so alte Versionen inzwischen
doch (verständlicherweise!) schwindet...

Grüße
TurboMagic

yogie 17. Mär 2019 08:41

AW: Threads und stack overflow bei Hardware am USB
 
... prima, auch am Wochenende gibt es Antworten.

Bei dem Buffer handelt es sich nur um zwei abwechselnd beschriebene statische Datenfelder. Das ist ausreichend, da es sich um langsame Vorgänge handelt. (alle 10 Minuten eine Messung speichern)

Ich habe jetzt mal die ganzen Threads usw. durch eine Simulation der
Daten ersetzt und bekomme trotzdem einen Gehler. Diesmal ist eine access violation, der stack overflow ist dann wohl ein Folgefehler. Damit hatte
ich nun garnicht gerechnet. Der Fehler tritt erst nach ca. 20 Minuten Laufzeit auf.

Für die Anzeige habe ich mir einen frame gebaut (nichts aufregendes nur ein paar edits und labels), den erzeuge ich beim Start 16 mal als Element
eines Feldes vom type frame. Da werden dann die Daten angezeigt. Ich muss dort mal weiter suchen.

Also threads und Hardware sind wohl erstmal nicht die Schuldigen.
Trotzdem: DANKE

peterbelow 17. Mär 2019 13:03

AW: Threads und stack overflow bei Hardware am USB
 
Stack overflows sind normalerweise Folge eines rekursiven Aufrufs einer Routine, eventuell auch indirekt (A -> B -> C -> A ...). Ohne den Kode deiner Execute-Methoden zu sehen (und wie dein Timer mit den Threads interagiert) ist eine weitere Diagnose nicht möglich. Aber ich habe da eher eine Programmierfehler im Verdacht, da der Fehler ja an der Zahl der Aufrufe zu hängen scheint, nicht an der Frequenz.

dummzeuch 17. Mär 2019 13:59

AW: Threads und stack overflow bei Hardware am USB
 
Neben dem, was Peter Below schrieb, gibt es noch den Fall, dass z.B. durch Application.ProcessMessages ein neuer Timer-Event ausgelöst wird, während der alte noch läuft.
Delphi-Quellcode:
procedure TMyForm.MyTimerTimer(Sender);
begin
  // Code
  Application.ProcessMessages;
  // mehr Code
  Application.ProcessMessages;
  // noch mehr Code
end;
Jedes Application.ProcessMessages kann dazu führen, dass der Timer neu ausgelöst wird, wenn der Code länger läuft als das Timer-Intervall.

Dabei läuft dann auch der Stack ganz langsam voll. Je kürzer das Intervall, desto schneller.

yogie 18. Mär 2019 10:05

AW: Threads und stack overflow bei Hardware am USB
 
Hallo zusammen,
nochmals danke!
Das Proplem ist gelöst. Der Stackoverflow hatte mich auf eine falsche Spur gesetzt.
Letzlich war es ein Timer-Event in Zusammenhang mit Application.ProcessMessages. Im Hintergrund liefen unsichtbar 16 kleine Grafiken mit, die erst auf Anforderung des Anwenders angezeigt werden sollen. Die hatte ich übersehen. Je mehr Daten die Grafiken enthielten, desto länger dauerte ihr refresh. Irgendwann war das dann zu lang. Ich denke der Stackoverflow war dann nur ein Folgefehler. Bei der Fehlersuche konnte och die Abbrüche auch ohne die Threads nur mit Dummy-Daten erzeugen. Fazit: wieder was gelernt und immer die komplette Verarbeitungskette anschauen, auch wenn sie für den Anwender unsichtbar ist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:57 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz