Programmabsturz ohne Fehlermeldung [Win2k]

Hallo Experten!

Ich bin zur Zeit auf der Suche nach der Ursache eines höchst interessanten Problems:
Folgende Ausgangssituation: Ein Programm (ca. 10 MB gross) und einige dazugehörige DLLs (zusammen nochmal ca. 10 MB) liegen auf einem Netzlaufwerk und werden von dort gestartet. Das Programm greift wieder übers Netz auf einen Oracle Server (anderer Server) zu. Das Programm selbst ist eine C++ Anwendung und mit VS 6.0 erstellt (allerdings nix MFC sondern auf einer externen class library [XVT] basierend).

Wenn ich nun das Programm starte, danach den Netzstecker ziehe (um intermittierende Netzprobleme zu simulieren) und im Programm versuche etwas zu tun, dann wird das Programm kommentarlos beendet (in den allermeisten Fällen, gaaaaanz spärlich gibt’s auch noch Fehlermeldungen vom Oracle Client, der sich über die verlorene Verbindung echauffiert). Das Problem tritt nicht auf, wenn ich Programm und DLLs von einer lokalen Platte ausführe - d.h. da regt sich der Oracle client natürlich immer noch auf, aber das Programm wird nicht kommentarlos beendet.

Jetzt kommt das eigentlich interessante: Bei dem von mir getesten Fall werden zwar noch einige Methoden korrekt ausgeführt, u.a. das Command Handling für den getesten Menü-Aufruf, aber beim Aufruf einer eigentlich recht trivialen Methode einer nicht abgeleiteten Klasse beendet sich das Programm. Hier kurz der Code, der sich verabschiedet:

long Klasse1::Methode1(long Par1, long Par2, char\* Par3)
{
 MyClass::Message("1"); // kommt noch
 return Klasse2::Methode2(Par1, Par2, Par3);
}

long Klasse2::Methode2(long, long, char\*)
{
 MyClass::Message("2"); // der kommt nimmer
 [...]
 return 4711L;
}

Selbstredend natürlich, dass der obige Code problemlos läuft, wenn die Netzwerkverbindung intakt ist.

Es sieht also sehr danach aus, als würde er entweder den Aufruf von MyClass::Message() beim zweiten mal nicht mehr schaffen (was ihm aber direkt davor noch gelungen ist) oder eben den Aufruf von Klasse2::Methode2() (erscheint mir wahrscheinlicher).

Meine Interpretation ist, dass das OS (Win2K Pro) versucht im am Server liegenden EXE irgendwas nachzulesen (warum eigentlich?) und weil das eben nicht geht den raschen Tod der Anwendung beschliesst.

Irgendwie scheint mir das aber ein so krasses Fehlverhalten zu sein, dass ich mir kaum vorstellen hier keinen Bug meinerseits eingebaut zu haben (falsche Linker-Parameter o.ä.).

Endlich meine Frage: Kennt jemand das Problem bzw. eine Lösung dazu (d.h. wie ich dem Anwender noch eine einigermassen vernünftige Meldung zukommen lassen kann)?

Danke für Eure Zeit und hoffentlich auch Hilfe,
Martin

Hallo Martin,

Meine Interpretation ist, dass das OS (Win2K Pro) versucht im
am Server liegenden EXE irgendwas nachzulesen (warum
eigentlich?) und weil das eben nicht geht den raschen Tod der
Anwendung beschliesst.

Einige Daten, wie z.B. alles was als Resurcen abgelegt ist, wird nicht in den Speicher geladen.

Irgendwie scheint mir das aber ein so krasses Fehlverhalten zu
sein, dass ich mir kaum vorstellen hier keinen Bug meinerseits
eingebaut zu haben (falsche Linker-Parameter o.ä.).

Es ist ganz normal, dass Windows nicht alles im Speicher behält, sondern bei Bedarf immer wieder Code (aus EXEs und DLLs) nachlädt, was in deinem Fall aber nicht mehr funktioniert. Das nächste Problem ist, dass Windows auch die DLLs nicht sauber entladen kann, da dazu die Funktion Exit in der DLL aufgerufen werden muss, welche ja gar nicht ansprechbar ist.
Möglicherweise müsste Windows auch zuerst die Dll zur Fehlerbehandlung zuerst laden …

Endlich meine Frage: Kennt jemand das Problem bzw. eine Lösung
dazu (d.h. wie ich dem Anwender noch eine einigermassen
vernünftige Meldung zukommen lassen kann)?

Ohne dein ganzes Projekt zu analysieren kann man da keinen Tip geben.
Die einzige Möglichkeit sehe ich darin alles als Debug-Version zu kompilieren und dann hoffen, das der Debugger einen Tip geben kann welche Fehlerbandlung du vergessen hast.
Weiterhin kann ich die nur noch empfehlen alles über DLLs in der Hilfe nachzulesen.

MfG Peter(TOO)

Hallo Peter!

danke erstmal für Deine Antwort!

Einige Daten, wie z.B. alles was als Resurcen abgelegt ist,
wird nicht in den Speicher geladen.

O.k., das hilft mir schon mal weiter beim Versuch das Problem auch zu verstehen. Ich war eigentlich advon ausgegangen, dass der Programmcode beim Start zur Gänze in den Speicher geladen wird (und von dort eventuell wieder gepaged wird, aber das hat ja mA mit dem Problem nichts zu tun).

Irgendwie scheint mir das aber ein so krasses Fehlverhalten zu
sein, dass ich mir kaum vorstellen hier keinen Bug meinerseits
eingebaut zu haben (falsche Linker-Parameter o.ä.).

Es ist ganz normal, dass Windows nicht alles im Speicher
behält, sondern bei Bedarf immer wieder Code (aus EXEs und
DLLs) nachlädt, was in deinem Fall aber nicht mehr
funktioniert. Das nächste Problem ist, dass Windows auch die
DLLs nicht sauber entladen kann, da dazu die Funktion Exit in
der DLL aufgerufen werden muss, welche ja gar nicht
ansprechbar ist.
Möglicherweise müsste Windows auch zuerst die Dll zur
Fehlerbehandlung zuerst laden …

Trotzdem bin ich der Meinung, dass das Programm in keinem Fall vom OS kommentarlos beendet werden dürfte…

Die einzige Möglichkeit sehe ich darin alles als Debug-Version
zu kompilieren und dann hoffen, das der Debugger einen Tip
geben kann welche Fehlerbandlung du vergessen hast.
Weiterhin kann ich die nur noch empfehlen alles über DLLs in
der Hilfe nachzulesen.

Hatte ich schon probiert, aber das hat mir auch nicht gerade weitergeholfen. Der Debugger bringt nur eine „unhandled Exception“, wobei ich eben der Meinung bin wirklich ALLE Exceptions bei mir richtig zu behandeln. Bin mir auch nicht ganz sicher, ob sich die Debug-Version in dem Fall nicht anders verhält als die Release-Version (was in mir immer wieder wahre Begeisterungsstürme auslöst).

Wenn das nicht so ins Geld gehen würde, dann würde ich ja mal dem MS-Support bemühen… Melde mich jedenfalls mit neuen Erkenntnissen.

Danke nochmal,
Martin

Hallo Martin,

Einige Daten, wie z.B. alles was als Resurcen abgelegt ist,
wird nicht in den Speicher geladen.

O.k., das hilft mir schon mal weiter beim Versuch das Problem
auch zu verstehen. Ich war eigentlich advon ausgegangen, dass
der Programmcode beim Start zur Gänze in den Speicher geladen
wird (und von dort eventuell wieder gepaged wird, aber das hat
ja mA mit dem Problem nichts zu tun).

Um das Pagefile nicht unnötig zu Vergrössern, werden nur veränderliche Speicherbereiche, also Daten, ausgelagert. Programmcode verändert sich ja nicht und kann deshalb jederzeit aus der entsprechenden .EXE oder .DLL wieder nachgeladen werden.

Möglicherweise müsste Windows auch zuerst die Dll zur
Fehlerbehandlung zuerst laden …

Trotzdem bin ich der Meinung, dass das Programm in keinem Fall
vom OS kommentarlos beendet werden dürfte…

MicroSoft stellt ein Workstation- her KEIN Netzwerk-Betriebssystem !
Das mitten im Betrieb eine Festplatte nicht mehr zur Verfügung steht, kommt nur bei einem Hardware-Deffekt vor.
Für dein Problem findet MS, dass man auf dem Server ein einen ein Server-Programm startet und dann über COM+ darauf zugreift.

Hatte ich schon probiert, aber das hat mir auch nicht gerade
weitergeholfen. Der Debugger bringt nur eine „unhandled
Exception“, wobei ich eben der Meinung bin wirklich ALLE
Exceptions bei mir richtig zu behandeln. Bin mir auch nicht
ganz sicher, ob sich die Debug-Version in dem Fall nicht
anders verhält als die Release-Version (was in mir immer
wieder wahre Begeisterungsstürme auslöst).

Mit dem Debugger kannst du aber nachsehen welche Exception das war.

Die Debug-Version unterscheidet sich hauptsächlich in folgenden Punkten:

  1. Der Code wird nicht optimiert (die Optimierung kann manchmal zu Fehlern führen).
  2. Im Debugger wird der Speicherpool (Heap) überwacht. Einerseits werden werden angeforderte Speicherblöcke vor dem Anfang und hinter dem Ende des Speicherblocks mit Markierungs-Werten gefüllt um ein „überfullen“ eines Blocks zu erkennen. Weiterhin werden an den Pool zurückgegebene Blöcke mit einer Konstanten gefüllt um das weitere Verwenden von freigegeben Speicherblöcken zu erkennen. Technisch wird einfach von Zeit zu Zeit nachgesehen ob diese Konstanten noch intakt sind, dadurch kann aber nicht festgestellt werden wer da was reingeschrieben hat.
  3. Das Programm läuft wesentlich langsamer.

MfG Peter(TOO)