![]() |
Gemeiner Programmabsturz, wie weiter machen?
Hi Forum.
Die Frage ist vielleicht etwas 'doof', aber ich war noch nie in dieser Situation. Darum wollte ich mal fragen, was ihr in so einem Fall macht, oder wie ich überhaupt weiterkomme. Also, Programm gebaut, sogar madExcept mit drin. Zuhause ist es schon seit Monaten nicht mehr abgestürzt, und absichtliche Exceptions zum testen zeigen mir auch das madExcept-Fenster wie gewünscht. Das Programm nutze ich, einfach um zu sehen, wie es so läuft, nebenbei auch auf der Arbeit. Manchmal verabschiedet es sich dann allerdings - kein madExcept kommt, einfach dieses Fenster "Programm hat ein Problem und muss beendet werden", dadrunter läuft dann diese Marquee-Progressbar, wie das seit Vista eben so ist. Nach ein paar Sekunden kommt dann die Frage, ob ich debuggen möchte. Habe hier allerdings kein Delphi, nur Visual Studio. Dann kann ich wohl zu der Adresse springen, wo es geknallt hat. Die Frage, die ich mir jetzt stelle, ist, ob mir diese Information irgendetwas bringt.. Das sieht bei einer der letzten Builds des Programms so aus:
Code:
Bei der aktuellen so:
004054CA je 004054D3
004054CC mov dl,1 004054CE mov ecx,dword ptr [eax] 004054D0 call dword ptr [ecx-4] <-- Bumm 004054D3 ret 004054D4 push ebx 004054D5 push esi
Code:
Wie würdet ihr mit diesem Problem jetzt weiter verfahren? Wie kommt man mit diesen Infos an die Stelle Delphi-Code, die hier Probleme macht? Oder wäre es am besten, Delphi auf diesem Rechner hier zu installieren? Ist nur etwas blöd, für den Firmenrechner eine Aktivierung mit meiner Lizenz durchzuführen..
0040550A je 00405513
0040550C mov dl,1 0040550E mov ecx,dword ptr [eax] 00405510 call dword ptr [ecx-4] <-- Bumm 00405513 ret 00405514 push ebx 00405515 push esi Würde mich sehr über Antworten sehr freuen! Liebe Grüße und TIA, Alex |
AW: Gemeiner Programmabsturz, wie weiter machen?
Kann man madExcept so einrichten, dass es lediglich im Debug-Modus anspringt? Nutze das leider nicht, aber denkbar wäre es. Daher könntest du evtl. auch nicht eine passende Meldung erhalten.
|
AW: Gemeiner Programmabsturz, wie weiter machen?
Man könnte das Problem indirekt durch exzessives Logging angehen.
Aber das ist nicht unbedingt optimal. Ich mache das bei all den Debugversionen meiner Projekte so! |
AW: Gemeiner Programmabsturz, wie weiter machen?
Das dem Programm die Handlungsfähigkeit (weit nach der Initialisierung) völlig entzogen wird, ist ja dann fast immer ein DEP-Problem, oder?
Die erste Frage wäre dann, ob die Bereichsprüfung eingeschaltet ist. |
AW: Gemeiner Programmabsturz, wie weiter machen?
Nachdem Delphi das Programm einmal ausgeführt hat und danach nicht geschlossen wurde, kannst du mit Suche->Laufzeitfehler die Adresse des Fehlers eingeben und kommst zu dem CPU-Fenster. Dort wird dir neben dem ASM-Code hoffentlich auch ein wenig deines Delphi-Codes angezeigt. Wenn nicht, dann ist das Pech.
Bernhard |
AW: Gemeiner Programmabsturz, wie weiter machen?
Danke erstmal für eure Antworten!
Zitat:
Zitat:
Zitat:
Zitat:
Nochmal vielen Dank für die Hilfe. |
AW: Gemeiner Programmabsturz, wie weiter machen?
Nun, so einfach dürfte das nicht gehen.
Die Imagebase Adresse kann und wird vom PE Loader geändert (warum - spielt keine Rolle). Deshalb solltest du, falls das Programm abstürtzt, nicht nur die Adresse, an die EIP zuletzt gezeigt hat, war merken, sondern auch die Imagebase. Und am besten merkst du dir nur die Differenz der beiden (Letzte Adresse - Imagebase). Dann hast du nämlich die relative virtuelle Adresse und kannst bei dir daheim dann deiner eigenen Imagebase (der Exe, zur Laufzeit ermittelt) diesen relativen Wert aufaddieren und hast letztendlich somit die Adresse, wo es geknallt hat. Ist schwer zu verstehen, wenn man keine Ahnung von PE (PortableExecutable Format) hat, aber du kannst gerne nachfragen, falls es dich interessiert. |
AW: Gemeiner Programmabsturz, wie weiter machen?
Liste der Anhänge anzeigen (Anzahl: 1)
Genau deswegen hatte ich ja auch geschrieben, möglichst Delphi nach dem Kompilat nicht mehr zu bedienen, da dann noch die Funktion aktiv ist und Delphi nicht neu kompiliert, wodurch sich alles ändern kann.
Bernhard ADD: Es gibt immer noch die Möglichkeit einer MAP-Datei. Darin steht dann, was wo im Speicher liegt. Das ist dann aber nicht mehr mein Gebiet. ADD2: Ich hab mal ein Screen hochgeladen, wo bei mir diese Option im Menü ist. |
AW: Gemeiner Programmabsturz, wie weiter machen?
Das hat nichts mit dem Kompilieren zu tun. Der PE Loader macht das zur Laufzeit, falls es nötig ist.
Auf verschiedenen Systemen (kommt darauf an, wie der RAM Speicher belegt ist), kann er verschieden reagieren! |
AW: Gemeiner Programmabsturz, wie weiter machen?
In dem Fall hat sich die Imagebase nicht geändert und es ist auch sehr unwahrscheinlich, dass sie sich beim Programm ändert. Setz im Programm nen Breakpoint am Start der aufgerufen wird und drück STRG+ALT+C dann STRG+G und gib die Adresse mit $ ein.
Im übrigen ist es sehr wahrscheinlich ein Aufruf von TObject.Free
Delphi-Quellcode:
Im übrigen kannst du auch Delphi installieren und die 30 Tage Testversion verwenden, musst es also nicht aktivieren.
00403559 E87A010000 call @ClassDestroy
0040355E C3 ret 0040355F 90 nop TObject.Free: 00403560 85C0 test eax,eax 00403562 7407 jz $0040356b 00403564 B201 mov dl,$01 00403566 8B08 mov ecx,[eax] 00403568 FF51FC call dword ptr [ecx-$04] 0040356B C3 ret TObject.InitInstance: 0040356C 53 push ebx 0040356D 56 push esi |
AW: Gemeiner Programmabsturz, wie weiter machen?
So.. ich schrieb hier einen ellenlangen Roman, wollte ein letztes mal in die Vorschau gucken, und dann war der rote Kasten da. Auf eine Antwort von brechi hofft man bei solchen Themen ja immer insgeheim ein bisschen. Die Sache von wegen "und gib die Adresse mit $ ein" hat mir weitergeholfen, dass das davor muss wusste ich nicht: Die Adresse liegt in TObject.Free() - und ich schätze jetzt mal, dass das Problem damit zusammenhängt, dass ich ein Objekt zweimal freigebe. Da könnte ich im zweifelsfall sogar mit Logging den Fehler finden. Oder gibt es eine Möglichkeit, ohne installiertes Delphi den Call-Stack zu bekommen? Ganz blöd gefragt, könnte ich das mit Visual Studio/Ollydbg/WinDbg sichtbar bekommen?
Nach etwas Testen gerade wurmt es mich aber, dass ein doppeltes .Free() in einem Testprogramm in .FreeInstance() abschmiert, nicht in .Free() wie im aktuellen Fall. Könnte es wirklich ein doppeltes Freigeben sein, oder ist das Problem u.U. ein anderes? Ausserdem springt madExcept in dem Fall an.. komisch. Deinen Edit gesehen, aber die Frage, ob es wirklich ein doppeltes Freigeben sein kann, bleibt für mich trotzdem noch.. Die Idee mit der Testversion ist übrigens sehr schön, das wird morgen direkt gemacht - und erledigt die Frage nach dem Callstack dann wohl auch teilweise, obwohl es mich interessieren würde, ob der Callstack auch ohne Delphi zu bekommen ist. Nochmal Danke an alle und einen schönen Abend noch! |
AW: Gemeiner Programmabsturz, wie weiter machen?
Den bekommst du auch mit OllyDbg. Wenn von Windows die Debugmeldung kommt mit Olly attachen, dann Debug drücken und F9 -> sollte an der Exception stehen bleiben (eben kurz getestet). ALT+K liefert den callstack oder halt unten rechts im Debugfenster.
Vill solltest du auch mal FreeAndNil verwenden (auch wenn unschön, da Free auf Nil testet) bzw. mit Assigned prüfen und ggf. Fehlermeldung ausgeben -> Assertion (nur wenn aus Delphi gestartet). |
AW: Gemeiner Programmabsturz, wie weiter machen?
Zitat:
Zitat:
Danke nocheinmal für deine Hinweise und die Mühen, ich fühle mich jetzt gerüstet für den Kampf. Wenn ich wieder mal nicht weiterkomme oder das Problem erledigt sein sollte, melde ich mich wieder. Gute Nacht, Alex |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:24 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz