Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   externe Exception c0000006 (https://www.delphipraxis.net/202018-externe-exception-c0000006.html)

UntoterGeist 18. Sep 2019 21:33

externe Exception c0000006
 
Hatte schon mal das Thema erstellt. Evl. gab es ja einen Fehler beim Erstellen. Zumindest findet man das Thema in der Forensuche und unter Themen mit Beteiligung. Also probiere ich es nochmal. Ein Mod war ja schon da. Hab ich gesehen.

Ich weiß es gibt Tonnen Informationen dazu im Internet mit Google und auch hier im Forum. Habe ich gelesen und verstanden. Wirklich!

Einleitung:

Ich schreibe auf Arbeit mit Delphi 2010 ein Datenbankprogramm mit der mysql.pas und der libmysql.dll. Darin werden nur Unternehmensintern Kundendaten und Lizenzschlüssel der Produkte erstellt und verwaltet. Es wird schon eingesetzt, weil wir "agile Entwicklung ausprobieren". Das bedeutet so alle 1-2 Wochen soll ein neues Release mit neuen Features kommen, die auch alle QM-Konform getestet werden müssen. Eher so jede Woche. Im Moment allerdings nicht.
Nun ist es so, eigentlich schon länger, dass wenn mein Chef das Programm aus dem Netzwerk startet und es einfach laufen lässt, es regelmäßig mal mehr mal weniger zu der Exception c0000006 (sind das genug Nullen?) kommt, wenn man es beenden oder irgendwas anderes machen will. Das Programm läuft bei ihm im Prinzip solange bis es abstürzt. Also auch übers Wochenende und länger. Wenn man das Programm, dass hab ich gefühlt 10k mal getestet, lokal startet kommt kein Fehler. Auch nicht nach 6 Stunden. Der Fehler tritt nur auf und das sehr häufig, wenn ich das Programm aus dem Netzwerk starte, laufen lasse und dann den Rechner mehrfach in den Standby schicke. Und irgendwann dann passiert es dann.
Die .dll wird dynamisch geladen weil's nicht anders geht. Ich hab so gut wie jede Programmzeile, die was mit der Datenbank zu tun hat, geloggt. Beim Beenden schmiert er dann aber beim Versuch ein Objekt freizugeben ab. Es ist immer das erste Objekt, wenn man es stückweise auskommentiert. Das wäre z.B. die Ressource oder das das LibHandle. Oder iwas auch immer danach kommt. Alle Objekte werden auf Nil getestet. Also sie sind in jedem Fall nicht Nil.
Es sind aber nicht nur Datenbankobjekte bei den es abraucht. Manchmal kommt der Fehler auch, wenn Fenster initialisiert werden. Genauer gesagt bei inherited Create(AOwner). Das ist die letzte Zeile die laut Log ausgeführt wird. AOwner ist in dem Fall Self aus dem Hauptfenster, dass regulär erstellt wird. Create wurde überladen, weil ich einen Parameter übergeben muss. Es kommt zwar eine Warnung, dass eine virtuelle Methode verborgen wird, aber es geht "eigentlich". In der mysql.pas kommen mehr Warnungen. Vor allem unsichere Pointer.
Ich habe sogar ein neues Delphi Projekt angelegt zum testen. Das selbe Scenario, die Datenbankobjekte werden beim Start initialisiert, sind nicht nil und beim free raucht es ab, wenn das Programm lange lief. Ich hab sogar ein Projekt angelegt, dass einen verfluchten einfachen Button dynamisch erzeugen soll. Konnte das aber noch nicht genau testen, ob es dann auch abschmiert. Evl. muss es ja auch ein Fenster oder etwas ähnliches sein. Allerdings hab ich keine Idee welches Objekt sonst noch den Parameter Self braucht und komplex genug ist.

Das Problem:

Wie kann ich den verdammten Fehler auflösen? Programm geht nicht!

Ich weiß, dass es die Kompileranweisungen gibt bei der das gesamte Programm in die Auslagerungsdatei geladen wird. Und wisst ihr was, der Fehler ist bei mir in der Experimental bisher nicht mehr aufgetreten. Egal was ich gemacht habe. Mir wurde aber praktisch verboten diese Anweisung zu benutzen, weil daran kann es nicht liegen. Außerdem wäre diese Methodik Try and Error und das geht überhaupt nicht. Und diese Anweisung wäre Missbrauch der Auslagerungsdatei. Das Netzwerk kann auch nicht schuld sein, weil: Dann müsste das ja größere Bahnen ziehen.

Der Fehler muss also im Code liegen und den Objekten die ich nicht sauber erstelle und Freigebe. Der Fehler liegt also bei mir und meinem Code! Den ich jetzt durchprüfen darf, weil da sind tausend Stellen die nicht sauber sind! Wirklich der ganze Code ist schrott!

Was soll ich jetzt eigentlich noch machen außer evl. Kündigen. Aber ansonsten ist alles tipitopi :thumb:

Hat jemand ne Idee was ich jetzt noch tun könnte?

Dalai 18. Sep 2019 21:48

AW: externe Exception c0000006
 
Das klingt mir danach, dass die PE Flags IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP und IMAGE_FILE_NET_RUN_FROM_SWAP helfen könnten. Siehe PE (Portable Executable) Header-Flags (Delphi).

Beispiel:
Delphi-Quellcode:
{$SetPEFlags IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP}
{$SetPEFlags IMAGE_FILE_NET_RUN_FROM_SWAP}
[EDIT]
Siehe auch hier bei StackOverflow: https://stackoverflow.com/questions/...-terminal-serv
[/EDIT]

Grüße
Dalai

UntoterGeist 18. Sep 2019 22:07

AW: externe Exception c0000006
 
Danke für die schnelle Antwort.

Aber das ist genau das, was ich in der Experimental gemacht habe. Und wie ich geschrieben hab, hat das "scheinbar" funktioniert, aber ich darf die Lösung so nicht umsetzten. Ich soll den Fehler im Code finden. Und ich befürchte einfach, dass ich das nicht kann. Weil es eben daran liegt das Programmteile aus dem Netzwerk nachgeladen werden sollen und der Zugriff durch irgendwas gestört ist. Mein Chef ist aber der Überzeugung, dass alles, also das gesamte Programm, in den RAM geladen wird und es deshalb keine Fehler geben könnte. Es muss also an mir und meinem Code liegen, so er.

Ich sehe gerade wie das Vertrauen in meine Fähigkeiten zerbröselt. Denn wir haben noch ein anderes Projekt an dem ich arbeiten soll und eigentlich muss.

samso 18. Sep 2019 22:34

AW: externe Exception c0000006
 
Werden die Datenbankverbindungen über die gesamte Laufzeit des Programms offen gehalten, oder wird bei jeder Benutzung der Datenbank die Verbindung neu initialisiert? Hast Du im Blick, dass der MySql-Server eine Verbindung die 8 (defaultwert) Stunden nicht genutzt wurde, einfach trennt?

UntoterGeist 18. Sep 2019 22:56

AW: externe Exception c0000006
 
Die Verbindung zur Datenbank wird standardmäßig schon nach ca. 10 Minuten vom Server getrennt. Gab früher schon mal Probleme damit. Es wird in einem Timer im Hauptmenu geprüft, ob die Verbindung noch steht, wobei man sich das schenken könnte, weil vor jeden Query die Verbindung mit ping geprüft und neu aufgebaut wird wenn es sein muss. Im Fehlerfall wird man auch ins Hauptmenu zurück geschickt. Sprich es wird ein Error zurück gegeben und nichts weiter ausgeführt. Ist inzwischen alles soweit verschachtelt. Im Prinzip muss die Verbindung nicht offen gehalten werden. Die Lib wird natürlich nicht neu eingebunden. Aber bei Free crasht es dann. Auch wenn vor Stunden und auch sonst noch alles lief.

Das assigned prüft ja auch nur auf Nil. Aber nicht, ob der Pointer noch gültig ist. Und da scheint das Problem zu sein. Die Objekte scheinen auf wundersame Weise ungültig zu werden und der Zeiger zeigt halt nur auf die Stelle die jetzt fremd belegt wird. Ich setzte auch die Pointer manuell auch Nil nach dem Free. Es sind auch nur 3 Funktionen was die Datenbank betrifft wo das passiert also recht überschaubar.

Dalai 18. Sep 2019 23:27

AW: externe Exception c0000006
 
Tja, nun, ein Programm wird aber nicht komplett in den Speicher geladen, weder unter Windows noch unter Linux, noch nicht einmal, wenn man die genannten PE-Flags setzt; die Flags sorgen nur dafür, dass das Programm aus dem Swap läuft statt vom Netzwerk/Wechseldatenträger, d.h. fehlende Pages kommen von der lokalen Platte statt vom ursprünglichen Ort. Dasselbe trifft auch auf DLLs zu. Will sagen: Wenn du die Flags setzt, dann muss das in allen beteiligten Teilen passieren. Wenn du Fremd-DLLs eingebunden hast, wird das schwierig bis unmöglich; dann könnte nur ein dynamisches Laden und Entladen der DLLs helfen.

Netzwerkverbindungen werden nun einmal getrennt, wenn man den Rechner schlafen legt. Und bei einem vom Netz laufenden Programm die Netzwerkverbindung zu trennen, führt dann sehr gern zu völlig unvorhergesehenem Verhalten und/oder Abstürzen (wie ich erst gestern selbst erleben durfte als ich ein Netzwerkkabel rausgezogen hatte...).

Grüße
Dalai

UntoterGeist 18. Sep 2019 23:44

AW: externe Exception c0000006
 
Zitat:

Zitat von Dalai (Beitrag 1446973)
Tja, nun, ein Programm wird aber nicht komplett in den Speicher geladen

Das erzähl mal meinem Chef. Für ihn ist das nicht mehr als ein Hello World Programm. Und das muss ja vollständig in den RAM geladen werden. Das hat er gestern (inzwischen) noch mal deutlich gesagt Mein Kollege geht da völlig d'accord. Und der hat das studiert! Woher die Gewissheit kommt weiß ich nicht. Entschuldigt meine Abfälligkeit. Aber ich bin etwas niedergeschlagen. Das Schlimmste ist das, Dalai, dein Vorschlag funktioniert, aber dieser abgelehnt wird. Aus genannten Gründen. Inzwischen wird mir auch so auf die Tastatur geschaut, dass ich mich nicht mehr wohl fühle. Alles scheint potentiell Falsch zu sein und ich muss alles doppelt und dreimal prüfen.

Das es tausende Beiträge zu dem Thema gibt ist auch nur die Bestätigung das es so nicht sein kann. Ich glaub das ist eig. mehr ein soziales Problem. Weil ich würde die Flags einfach setzten und das eine Woche testen. Für meinen Chef ist so eine Methodik aber unprofessionell.

mensch72 19. Sep 2019 05:02

AW: externe Exception c0000006
 
Einfache & pragmatische Lösung:
- mache eben wie "gewollt" das Programm ohne besondere PE Flags
- binde die EXE als Resource in ein zusätzliches kleines "FullfileLoaderProgramm" ein
- kopiere also im Loaderprogramm einfach nur 1x die Resource in z.B. das lokale "ProgrammData" Verzeichnis, starte die EXE dort "lokal" via ShellExecute und beende das Loaderprogramm

So startet dein Chef bei ja aktivem Netzwerk problemlos das "LoaderProgramm", es lädt wegen Zugriff auf die riesige Resource definitiv 1x komplett vom Netzwerk auf den PC(wie er ja unbedingt will) und ab da läuft es dann wie er ja auch will lokal...

=> Chefe hat seinen Willen und Programm funktioniert:)

samso 19. Sep 2019 06:18

AW: externe Exception c0000006
 
Zitat:

Zitat von mensch72 (Beitrag 1447011)
Einfache & pragmatische Lösung:
- mache eben wie "gewollt" das Programm ohne besondere PE Flags
- binde die EXE als Resource in ein zusätzliches kleines "FullfileLoaderProgramm" ein
- kopiere also im Loaderprogramm einfach nur 1x die Resource in z.B. das lokale "ProgrammData" Verzeichnis, starte die EXE dort "lokal" via ShellExecute und beende das Loaderprogramm

So startet dein Chef bei ja aktivem Netzwerk problemlos das "LoaderProgramm", es lädt wegen Zugriff auf die riesige Resource definitiv 1x komplett vom Netzwerk auf den PC(wie er ja unbedingt will) und ab da läuft es dann wie er ja auch will lokal...

=> Chefe hat seinen Willen und Programm funktioniert:)

So einfach wird es nicht sein. Die Kollegen scheinen sich ja sehr genau anzuschaun was da innerhalb des Programms getrieben wird. So wie die ticken, wird ein solches Vorgehen als ein weiterer Beleg für die Unfähigkeit des Programmierers gewertet dieses Problem in den Griff zu bekommen. Schon das Setzen des PE-Flags wird ja als Workaround gewertet. Die Gegenfrage ist doch eigentlich, weshalb gibt es dieses Flag überhaupt, wenn es doch nicht notwendig ist.

Kennt jemand vielleicht ein Tool, dass so eine Art Speicherauszug erzeugt. Es wäre ja schön, wenn man zeigen könnte, welche Teile des Programms tatsächlich im RAM liegen und welche Teile sich nur auf dem Netzwerklaufwerk befinden und bei Bedarf von dort nachgeladen werden.

Alternativ würde ich versuchen das Fehlerbild mit einem aufwändigen Versuchsaufbau zu reproduzieren. Dazu ist es zunächst notwendig den Speicherort der Exe und den SQL-Server auf unterschiedlichen Netzwerkrechnern zu halten. Nun würde ich versuchen durch Trennen der Netzwerkverbindung des "Exe-Hosts" den Swap-Fehler zu provozieren. Wenn das möglich ist, zeigt mir das, dass der Fehler nicht dadurch hervorgerufen wird, dass die Netzwerkverbindung zum SQL-Server abbricht, sondern dass es nur etwas mit den auslagerten Teilen der ausführbaren Datei zu tun hat.

hoika 19. Sep 2019 06:29

AW: externe Exception c0000006
 
Hallo,
lass Deine Kollegen #2 ausgiebig durchlesen.
Und wenn Sie das nicht begreifen, komm zu uns ;)

Das Problem ist der Server, nicht dein Programm.

Google "delphi c0000006 network"

http://devzone.advantagedatabase.com...No=101230-2385
Unten steht dort der MS-Hotfix dafür.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:31 Uhr.
Seite 1 von 3  1 23      

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