Entwickler-Ecke

Sonstiges (Delphi) - Programm mit Threads hängt sich nach ein paar Tagen auf


Bronstein - Mi 16.04.14 07:53
Titel: Programm mit Threads hängt sich nach ein paar Tagen auf
Hallo zusammen,
ich habe ein Programm das sich nach 1-2 Tagen einfach aufhängt.

Möchte ich das Programm dann neustarten erscheint die Fehlermeldung "Es wird versuch das Problem zu identifizieren..."

Möchte ich dann den Taskmanger starten bekommen ich folgende Fehlermeldung: "Die Anwendung konnte nicht korrekt gessartet werden (0xc0000142). Klicken Sie auf "OK", um die Anwednung zu schließen"

Das einzige was jetzt hilft ist den Rechner neuzustarten.

Kurz zu der Anwendung:
Es handelt sich um ein Programm, das mit Threads arbeitet. Diese Threads rufen dann über DLLs Daten von Maschinen ab und speichern diese per AdoComponenten in einer DB2 Datenbank. Bei den Dlls werden ebenfalls über AdoComponenten auf Datenbanken zugegriffen.

Komponenten die ich zur Laufzeit erzeuge werden auch alle wieder beendet. Die Graphischen-Komponenten habe ich auch mal komplett aus der Anwendung genommen, so dass der Zugriff aus einem Thread auf diese auch nicht der Grund sein kann.


Nersgatt - Mi 16.04.14 08:07

Bist Du sicher, dass beim Neustartversuch der ursprüngliche Prozess komplett beendet ist?
Schau mal in dem Fall im Taskmanager unter "Prozesse", ob der Prozess dort noch aufgeführt wird.

Und dann würde ich mal den Speicherverbrauch (auch im Taskmanager) über längere Zeit beobachten. Wenn es kontinuierlich ansteigt, spricht das dafür, dass da doch irgendwas nicht richtig freigegeben wird. In dem Fall hilft dann FastMM im Fulldebugmode weiter.


Blup - Mi 16.04.14 09:20

Am besten lassen sich solche Fehler mit Stress-Tests reproduzieren und finden.
Bau dir Tests die ein vielfaches des normalen Datenaufkommens simulieren.


jaenicke - Mi 16.04.14 09:51

user profile iconBronstein hat folgendes geschrieben Zum zitierten Posting springen:
Möchte ich dann den Taskmanger starten bekommen ich folgende Fehlermeldung: "Die Anwendung konnte nicht korrekt gessartet werden (0xc0000142). Klicken Sie auf "OK", um die Anwednung zu schließen"
Das deutet darauf hin, dass du irgendwelche Systemressourcen stark beanspruchst, so dass z.B. Objekte im Kernel Speicher liegen bleiben. Die werden auch nicht immer sauber aufgeräumt, wenn das Programm abgeschossen wird. Und FastMM kann dir bei solchen Sachen auch nicht helfen.

Bei einem Programm, das über längere Zeiträume läuft, sollte natürlich eine Null-Fehler-Grenze gelten was Speicherlecks usw. angeht, sprich FastMM sollte keine finden, zumindest keine, die während der Nutzung mehr werden. Trotzdem hilft das nicht unbedingt in diesem Fall.

Was du machen kannst ist einerseits im Code zu schauen, ob irgendwo Systemobjekte reserviert werden (im Zweifelsfall: alles was ein Handle hat, Regions, Fensterhandle, ...) und nicht wieder freigegeben werden. (Beliebt ist z.B. GetDC(0) um einen Screenshot zu machen.)
Und andererseits zeigt der Process Explorer, den du von Microsoft herunterladen kannst, in den Eigenschaften eines Prozesses unter Performance unten rechts die Anzahl an Handles an. Nimmt die mit der Zeit zu, stimmt in der Regel etwas nicht.


Narses - Mi 16.04.14 10:18

Moin!

user profile iconBronstein hat folgendes geschrieben Zum zitierten Posting springen:
Die Graphischen-Komponenten habe ich auch mal komplett aus der Anwendung genommen, so dass der Zugriff aus einem Thread auf diese auch nicht der Grund sein kann.
Wenn du hier VCL-Komponenten meinst und unsynchronisiert darauf zugreifst, dann kann alles mögliche passieren. :hair: Die VCL (und logischerweise davon abgeleitete Komponenten) sind nicht thread-save (falls du das nicht bereits kanntest)! :idea:

cu
Narses


GuaAck - Mi 16.04.14 20:23

Hallo Bronstein,

auch Dlls müssen nicht unbedingt threadsicher sein - jedenfalls haben wir aktuell mit der mehrfachen Nutzung einer DLL ein Problem, wir müssen die DLL für den zweite Nutzung umbenennen, damit sie doppelt geladen wird, dann geht es.

Ich hatte mir letztens bei so einem Problem einen eigenen Log-Thread gemacht, der läuft dann weiter, wenn der Rest im Deadlock ist. Bei Deadlock habe ich dann einfach einen Breakpoint auf einen Befehl in dem Thread gesetzt, dann konnte ich den Puffer lesen; hat mir geholfen, schnell den Übeltäter zu finden. Du könntest auch einen Zähler einbauen, der den Puffer in eine Datei schreibt, wenn eine bestimtme Zeit lang nichts mehr gekommen ist.

Quellcode anbei (Quick and dirty gemacht, also als Rohling für Deine eigenen Dinge zu verstehen. Das Windows Message-System habe ich bewusst nicht benutzt, weil damit die zeitliche Reihenfolge der Einträge nicht garantiert wäre.)

Viel Erfolg
Gruß GuaAck