Konsolenfenster bleibt nach Absturz während Debugging offen und PC läßt nicht sich herunterfahren
-
Hallo,
ich habe da ein merkwürdiges Verhalten von VS2005.
Ich arbeite unter Windows XP und verbinde in meiner main() einen Pointer vom Typ Board (ist ein Interace) mit einer Instanz vom Typ SpecialBoard (public von Board abgeleitet) über LoadLibrary(). Die Instanz wird in der jeweiligen DLL erzeugt und über eine GetInstance() wird eben die Adresse dieser Instanz zurückgegeben und dem Basisklassenzeiger zugewiesen.
Also das klappt alles super und ich kann auch mit dem Methoden von SpecialBoard arbeiten. Aber wenn der Compiler beim Debuggen sich gerade in einer Funktion der Klasse SpecialBoard befindet und dort abstürzt, zB wegen Zugriff auf NULL, dann beende ich das Debugging in VS2005 das korrekt, aber das Konsolenfenster bleibt offen. Aber es kommt noch schlimmer
Ich kann das Fenster nicht mehr manuell schließen und selbst den Computer kann ich nicht mehr herunterfahren. Ich kann zwar das Fenster dazu aufmachen und so, aber er tut einfach nix. Es hilft echt nur noch ausschalten. Destruktoren sind eingebaut, werden die beim Beenden Debugging noch aufgerufen? Wenn ich Anhaltspunkt hätte wo ich suchen muß? Kanne es überhaupt am Compiler liegen? Wenn nein Beitrag bitte ins richtige Forum verweisen, danke.
Was kann das sein, ich bin mit meinem Latein echt am Ende.
Danke.
-
Das merkwürdige Verhalten kommt nicht von VS2005, sondern von fehlerhaften Programmen/Treibern.
Normaler Weise wird ein Prozess sauber vom Debugger/Betriebsystem "gekillt". Die Destruktoren werden zwar nicht mehr aufgerufen, aber das ist meistens kein Problem, weil das Betriebsystem weiss, welche Handels der Prozess offen hat und sich um das Aufgeräumen kümmert. Probleme kann es z.B. geben, wenn du es irgentwie geschafft hast, mehrere Instanzen deiner DLL zu laden. Da dann die DLL nicht entladen wird und die dort geöffneten Handle (z.B. zum Gerätetreiber) dann natürlich offen bleiben. Kritisch ist es manchmal auch, wenn Exception im Kernel ausgelöst wurden (Fehlerhaft arbeitenter Gerätetreiber?).
Hast du im Taskmanager nachgeschaut, ob da eine oder sogar mehrere Instanzen deines Programms angezeigt werden? Lassen die sich mit Affengriff abwürgen?
Von Sysinternal (jetzt Microsoft), gibt es ein Process Explorer http://technet.microsoft.com/de-de/sysinternals/bb896653.aspx, mit dem man solche Problemfälle auf dem Grund gehen kann. Echt genial das Teil, kann ich nur empfehlen.
-
Also erstmal danke für deine Antwort, bin im Moment echt für jede Anregung dankbar.
Also im Taskmanager sieht man unter Anwendungen das Konsolenfenster, aber man kann es auch dort nicht mehr beenden. Und unter Prozesse habe ich es nicht gefunden.
Die dll habe ich wie gesagt ja selbst geschrieben und benutze sie eben mit LoadLibrary().
Ich glaube auch, dass das Problem irgendwas mit den Dlls zu tun hat.Was meinst du genau mit mehrere Instanzen der Dll laden? Meinst Du mehrmals mit Loadlibrary() die selbe DLL laden?
Grüße
-
VS_beginner schrieb:
Was meinst du genau mit mehrere Instanzen der Dll laden? Meinst Du mehrmals mit Loadlibrary() die selbe DLL laden?
Pro Prozess kann man eine DLL nur einmal laden. Mehrfacher Aufruf von Loadlibrary() bewirkt nichts, es wird jedesmal das selbe Handle zurückgegeben, der Referenzzähler wird dabei nicht hoch gezählt. Wenn du dein Programm aber nochmal startest, z.B. außerhalb der IDE, dann ist diese EXE eine neue Programm-Instanz im Speicher. Ruft diese Loadlibrary() auf, wird die DLL nicht noch einmal in den Speicher geladen (das ist ja der Sinn von DLLs). Es wird einfach ein zum DLL-Handle gehöhrender Referenzzähler hochgezählt. Die DLL wird erst entladen, wenn dieser Referenzzähler wieder auf Null runtergezählt wurde, d.h. alle Prozesse, die die DLL benutzen, diese wieder frei gegeben haben durch CloseHandle() oder durch das BS beim Killen des Prozesses.
Wenn sich der Prozess nicht im Taskmanager beenden läßt, dann liegt das höchstwahrscheinlich daran, dass er Betriebsystem-Ressourcen noch in Benutzung hat, die sich nicht sauber vom Prozess trennen lassen, z.B. wenn der Gerätetreiber auf Beenden-Signale des BS nicht mehr reagiert. Da unabhängig davon der Debugger es manchmal schafft, sich vom Prozess abzukoppeln, kann es zu den von dir geschilderten Verhalten kommen.
Selbst wenn sich nun der Debugger neu starten läßt, wird zwar eine neue Programminstanz geladen, diese nutzt dann aber die im Speicher verbliebene DLL. Mann kann sich das so vorstellen, als würde die DLL am (offenen) Treiber kleben. Man bekommt die DLL nur noch durch booten aus dem Speicher. Bei ein sauber programmierten Treiber sollte das nicht passieren.
Vermutlich hast du keinen Möglichkeit etwas am Treiber zu tun. Und der Hersteller hat ja die Ausrede, dass der Treiber gut funktioniert, wenn man ihn richtig benutzt. Es wird dir also nichts weiter übrig bleiben, die Inneraktion deiner DLL mit den Treiber genaustens zu protokollieren und an hand dessen die Ursache für das Problem zu finden. Da sich DLLs schlechter Debuggen lassen als Programme, würde ich versuchen, für das weitere debuggen den DLL-Code direkt in die Exe zu linken.
Nur so als weiterer Gedankenanstoß, ein genaueres Eingehen ist von fernen nicht möglich: Du musst peinlichst darauf achten nur Funktionen multithreaded zu benutzen, die threadsicher sind. Einfache Regel: Keine DLL-Programmieren ohne gründliche Checks in Richtung Multithreading. Ein Debugging-Trick von mir ist, sich die Thread-ID ausgeben zu lassen, an allen Eintrittpunkten zu nicht threadsicheren Programmteilen. Da du vermutlich ein Gerät ansprichst, dass nur von einen Programm benutzt werden soll und die DLL nur dazu benutzen willst, um das Gerät "Programiersprachen unabhängig" (z.B. LabView) anzusprechen - könnte ich mir gut vorstellen, dass du dir darüber noch keine Gedanken gemacht hast. Der Programmierer des Basis-Interfaces hat es aber hoffentlich, weil sonst eine Benutzung in einer DLL ziemliche Fallstricke legen kann.
-
Siehe Diskussion hier:
http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.de.vc&tid=f53e1f2d-97eb-4447-8652-809758d7ae32&cat=de_DE_a2ca88d2-2b67-42ff-be30-3fe02a459e88&lang=de&cr=DE&sloc=&p=1Speziell die Verweise im letzten Posting:
http://social.answers.microsoft.com/Forums/en-US/vistawu/thread/64edc1fe-94dc-4f44-8e17-03331a203ac8
http://social.msdn.microsoft.com/Forums/en-US/vsdebug/thread/e6d4a4f5-7002-401a-90e1-6174d7f9e3ca