Wie ein Call-Stack lesen?
-
06-07-2019 - |
Frage
Wir haben eine native C ++ Anwendung auf einem Windows 2003 Server über COM + ausgeführt wird. Ich habe vor kurzem von der Ereignisanzeige festgestellt, dass sein Wurf Ausnahmen, nämlich die C0000005 Ausnahme, die nach
Lösung Wenn Sie wirklich diese Adressen auf Ihre Funktionen benötigen abzubilden -. Sie müssen mit .MAP Datei arbeiten und sehen, wo diese Adressen verweisen auf wirklich Aber in Ihrer Situation zu sein, würde ich eher untersuchen dieses Problem unter Debugger (z MSVS Debugger oder windbg); als Alternative (wenn Absturz vor Ort beim Kunden geschieht) können Sie Crash-Dump erzeugen und lokal studieren - es via Windows MiniDumpWriteDump API oder SysInternals ProcDump Dienstprogramm ( http://download.sysinternals.com/Files/procdump.zip ). Stellen Sie sicher, dass alle erforderlichen Symboldateien generiert und zur Verfügung (auch Microsoft Symbol Server-Pfad-Setup, so dass Windows-DLLs' Einstiegspunkte auch gelöst bekommen). IMHO das ist nur die Website, die Sie brauchen: http://www.dumpanalysis.org - die Ressource ist die beste alle Ihre Fragen zu decken.
Sehen Sie sich auch einen Blick auf diese PDF unter - http://windbg.info/download/doc /pdf/WinDbg_A_to_Z_color.pdf
Andere Tipps
Andere sagen, haben dies in-zwischen den Zeilen, aber nicht explizit. Blick auf:
LibFmwk!UTIL_GetDateFromLogByDayDirectory(char const *,class utilCDate &) + 0xa26c
Die 0xa26c Offset große , Art und Weise über das Ende der Funktion. der Debugger offensichtlich die richtigen Symbole für LibFmwk nicht so haben, anstatt sie auf die DLL-Exporte verlassen und zeigt den Versatz in Bezug auf die nächste man es finden kann.
Also, ja, bekommen richtige Symbole und dann soll es ein Kinderspiel. UTIL_GetDateFromLogByDayDirectory ist hier nicht schuld.
Punkt 2 und 3 sind leicht zu beantworten:
3. Punkt. Alle Debugger. Das ist, was sie gemacht werden für. Stellen Sie Ihren Debugger auf dieser speziellen Ausnahme zu brechen. Sie sollten in der Lage sein, sich durch die Aufrufliste klicken und die verschiedenen Anrufe auf dem Stapel finden (zumindest delphi dies tun können, so Visual Studio als auch in der Lage sein sollte). Kompilieren ohne Optimierungen, wenn möglich. OllyDBG könnte genauso gut funktionieren -. Vielleicht in Kombination mit der Trace-Funktionalität
2. Punkt. Alle Informationen über x86 Assembler, Reverse Engineering ... Versuchen: OpenRCE NASM Dokumentation , ASM Gemeinschaft .
1. Punkt. Die Aufrufliste zeigt Ihnen die Funktionen. Ich weiß nicht, ob es in Ordnung oder in umgekehrter Reihenfolge geschrieben wird - so es sein könnte, dass die erste Zeile ist die letzte aufgerufene Funktion oder die ersten aufgerufene Funktion. Folgen Sie den Anrufe mit Hilfe des Debuggers. Manchmal kann man zwischen asm und Code ändern (abhängig von der Debugger, Map-Dateien ...). Wenn Sie nicht die Quelle haben - lernen Assembler, lesen Sie über Reverse Engineering. Lesen Sie die Dokumentation der Funktionen, die Sie in Komponenten von Drittanbietern aufrufen. Vielleicht erfüllen Sie keine Voraussetzung.
Wenn Sie ein bisschen mehr über das Programm sagen kann (die Teile des Quellcodes haben Sie haben, ist eine Bibliothek Anruf beteiligt ?, ...)
Jetzt sind einige Code-Lesung:
Die Funktion übernimmt einen Zeiger auf einen Null-terminierten String und einen Verweis auf ein Date-Objekt. Der Zeiger wird angenommen, gültig sein!
Die Funktion überprüft, ob die Zeichenfolge in einem bestimmten Format (% gefolgt von 8 Ziffern, gefolgt von einem \ 0). Ist dies nicht der Fall ist, gibt es falsch. Diese Prüfung (die große if) greift auf den Zeiger ohne Gültigkeitsprüfungen. Die Länge wird nicht geprüft, und wenn der Zeiger irgendwo in der Wildnis zeigt, wird dieser Raum abgerufen. Ich weiß nicht, ob eine kürzere Zeichenfolge wird zu Problemen führen. Es soll nicht wegen der Art und Weise && ausgewertet wird.
Dann wird ein Teil des Speichers auf dem Stapel zugeordnet. Das zahlt Teil der Zeichenfolge in sie kopiert (was in Ordnung ist), und der Puffer erhält seine \ 0 Terminierung. Die atois extrahieren Sie die Zahlen. Dies funktioniert aufgrund der unterschiedlichen Start-Standorte eingesetzt und die \ 0-Terminierung nach jedem Teil. Irgendwie schwierig, aber nett. Einige Bemerkungen wäre alles klar gemacht.
Diese Zahlen werden dann in das Objekt eingefügt. Es sollte gültig sein, da er in die Funktion als Referenz übergeben wird. Ich weiß nicht, wenn Sie einen Verweis auf ein gelöschtes Objekt übergeben können, aber wenn dies der Fall ist, könnte dies Ihr Problem als gut.
Wie auch immer - außer die fehlende Überprüfung auf die String-Zeiger, diese Funktion ist solide und nicht die Ursache des Problems. Es ist nur der Ort, der die Ausnahme auslöst. Suche nach Argumenten, die in diese Funktion übergeben werden. Sind sie immer gültig? Sie einige der Protokollierung.
Ich hoffe, ich habe keine großen Fehler machen, wie ich ein Delphi-Programmierer bin. Wenn ich das täte -. Fühlen Sie sich frei zu äußern