Heisenbug: WinApi Programm stürzt auf einigen Computern ab

8

Bitte helfen Sie! Ich bin wirklich am Ende meiner Weisheit. Mein Programm ist ein kleiner persönlicher Notizenmanager (google für "cintanotes"). Auf einigen Computern (und natürlich besitze ich keine von ihnen) stürzt es direkt nach dem Start mit einer unbehandelten Ausnahme ab. Nichts Besonderes über diese Computer könnte gesagt werden, außer dass sie AMD CPUs haben.

Umgebung: Windows XP, Visual C ++ 2005/2008, Roh-WinApi.

Hier ist das, was über diesen "Heisenbug" sicher ist:

1) Der Absturz passiert nur in der Release-Version.

2) Der Absturz verschwindet, sobald ich alle GDI-bezogenen Sachen entfernt habe.

3) BoundChecker hat keine Beschwerden.

4) Das Schreiben eines Protokolls zeigt, dass der Absturz bei einer Deklaration einer lokalen int-Variablen auftritt! Wie kann das sein? Speicherbeschädigung?

Irgendwelche Ideen würden sehr geschätzt werden!

UPDATE: Ich habe es geschafft, die App auf einem "fehlerhaften" PC zu debuggen. Die Ergebnisse:

"Nicht behandelte Ausnahme bei 0x0044a26a in CintaNotes.exe: 0xC000001D: Illegal Instruction."

und Code bricht an

0044A26A cvtsi2sd xmm1, dword ptr [esp + 14h]

Es scheint also, dass das Problem in der Compileroption "Code Generation / Enable Enhanced Instruction Set" lag. Es wurde auf "/ arch: SSE2" gesetzt und stürzte auf den Maschinen ab, die SSE2 nicht unterstützten. Ich habe diese Option auf "Not Set" gesetzt und der Fehler ist weg. Puh!

Vielen Dank für die Hilfe !!

    
Alex Jenter 08.10.2008, 08:02
quelle

11 Antworten

5

Es stürzt also nicht bei der Konfiguration der DEBUG-Konfiguration ab? Es gibt viele Dinge, die sich von einer RELEASE-Konfiguration unterscheiden: 1.) Initialisierung von Globalen 2.) Aktueller Maschinencode generiert usw. ..

Zuerst müssen Sie herausfinden, welche genauen Einstellungen für jeden Parameter im RELEASE-Modus im Vergleich zum DEBUG-Modus gelten.

-AD

    
goldenmean 25.09.2008, 08:38
quelle
10
  

4) Writig ein Protokoll zeigt, dass der Absturz auf eine Deklaration einer lokalen int-Variable passiert! wie kann das sein? Speicherbeschädigung?

Was ist der zugrunde liegende Code in der ausführbaren Datei / Assembly? Die Deklaration von int ist überhaupt kein Code und kann daher nicht abstürzen. Initialisierst du den Int irgendwie?

Um den Code zu sehen, wo der Absturz passiert ist, sollten Sie eine sogenannte Postmortem-Analyse durchführen.

Windows Fehlerbericht

Wenn Sie den Absturz analysieren möchten, sollten Sie einen Absturzspeicherauszug erhalten. Eine Möglichkeit ist, sich für die Windows-Fehlerberichterstattung anzumelden - erfordert etwas Geld (Sie benötigen eine digitale Code-Signatur-ID) und einige Formulare ausfüllen. Weitere Informationen finden Sie Ссылка .

Holen Sie sich den für WER vorgesehenen Absturzspeicherauszug direkt vom Kunden

Eine weitere Möglichkeit besteht darin, sich mit einem Benutzer, der den Absturz erlebt, in Verbindung zu setzen und direkt von ihm einen Absturzspeicher für WER zu erhalten. Der Benutzer kann dies tun, wenn er auf die technischen Details klickt, bevor er den Absturz an Microsoft sendet - dort kann der Speicherort der Absturzspeicherdatei überprüft werden.

Ihr eigener Minidump

Eine andere Möglichkeit besteht darin, einen eigenen Exception-Handler zu registrieren, die Exception zu behandeln und einen beliebigen Minidump zu schreiben. Eine detaillierte Beschreibung finden Sie unter Code Project Post-Mortem Debuggen Ihrer Anwendung mit Minidumps und Visual Studio .NET Artikel .

    
Suma 25.09.2008 08:46
quelle
4
  

1) Der Absturz passiert nur in der Release-Version.

Das ist normalerweise ein Zeichen, dass Sie sich auf ein Verhalten verlassen, das nicht garantiert ist, aber im Debug-Build wahr ist. Zum Beispiel, wenn Sie vergessen, Ihre Variablen zu initialisieren, oder auf ein Array außerhalb der Grenzen zugreifen. Stellen Sie sicher, dass Sie alle Compiler-Prüfungen (/ RTCsuc) aktiviert haben. Überprüfen Sie auch Dinge wie die Reihenfolge der Auswertung von Funktionsparametern (was nicht garantiert ist).

  

2) Der Absturz verschwindet, sobald ich alle GDI-bezogenen Sachen entfernt habe.

Vielleicht ist das ein Hinweis darauf, dass Sie mit dem GDI-Thema etwas falsch machen? Verwenden Sie zum Beispiel GRIFFE nachdem sie freigegeben wurden?

    
Anthony Williams 25.09.2008 08:43
quelle
2

Laden Sie das Debugging-Tool für Windows herunter. Stellen Sie die Symbolpfade korrekt ein und führen Sie Ihre Anwendung unter WinDbg aus. Irgendwann wird es mit einer Zugriffsverletzung brechen. Dann sollten Sie den Befehl "! Analyze -v" ausführen, was ziemlich schlau ist und Ihnen einen Hinweis darauf geben sollte, was schief läuft.

    
user15071 25.09.2008 10:09
quelle
1

Die meisten Heisenbugs / Nur-Release-Bugs sind entweder auf den Fluss der Kontrolle zurückzuführen, der von Lesevorgängen aus nicht initialisierten Speicher / veralteten Zeigern / vergangenem Ende von Puffern oder Rennbedingungen oder beiden abhängt.

Überschreiben Sie Ihre Zuordner, damit sie bei der Zuweisung keinen Speicher mehr haben. Geht das Problem weg (oder wird es besser reproduzierbar?)

  

Writig ein Protokoll zeigt, dass der Absturz bei einer Deklaration einer lokalen int-Variable passiert! Wie kann das sein? Speicherbeschädigung?

Stapelüberlauf! ;)

    
moonshadow 25.09.2008 08:37
quelle
1
  

4) Writig ein Protokoll zeigt, dass der Absturz auf eine Deklaration einer lokalen int-Variable passiert! Wie könnte das sein? Speicherbeschädigung

Ich habe die Ursache für zahlreiche "seltsame Abstürze" gefunden, die auf die Dereferenzierung eines defekten this in einer Memberfunktion des Objekts hinweisen.

    
Johann Gerell 25.09.2008 09:05
quelle
1

Was sagt der Absturz? Zugriffsverletzung ? Ausnahme? Das wäre der weitere Anhaltspunkt, um dies zu lösen mit

Stellen Sie sicher, dass Sie keine vorangegangenen Speicherbeschädigungen mit PageHeap.exe haben

Stellen Sie sicher, dass Sie keinen Stapelüberlauf haben (CBig-Array [1000000])

Stellen Sie sicher, dass Sie keinen nicht initialisierten Speicher haben.

Außerdem können Sie die Release-Version auch innerhalb des Debuggers ausführen, nachdem Sie Debug-Symbole (nicht das gleiche wie beim Erstellen der Debug-Version) für den Prozess generiert haben. Gehen Sie durch und überprüfen Sie, ob im Debugger-Trace-Fenster Warnungen angezeigt werden.

    
computinglife 25.09.2008 10:02
quelle
1

"4) Das Schreiben eines Protokolls zeigt, dass der Absturz bei einer Deklaration einer lokalen int-Variablen passiert! Wie könnte das sein? Speicherbeschädigung?"

Dies könnte ein Zeichen dafür sein, dass die Hardware tatsächlich fehlerhaft ist oder zu stark gedrückt wird. Finden Sie heraus, ob sie ihren Computer übertaktet haben.

    
Mike Dimmick 25.09.2008 12:40
quelle
1

Wenn ich diese Art von Sache bekomme, versuche ich, den Code über gimpels PC-Lint (statische Codeanalyse) auszuführen, während er verschiedene Klassen von Fehlern nach BoundsChecker überprüft. Wenn Sie BoundSchecker verwenden, aktivieren Sie die Speicher-Poisoning-Optionen.

Sie erwähnen AMD-CPUs. Haben Sie untersucht, ob auf den abstürzenden Maschinen eine ähnliche Grafikkarte / Treiberversion und / oder Konfiguration vorhanden ist? Stürzt es immer auf diesen Maschinen oder nur gelegentlich ab? Vielleicht führen Sie das System Information Tool auf diesen Maschinen aus und sehen Sie, was sie gemeinsam haben,

    
Shane MacLaughlin 26.09.2008 07:32
quelle
1

Klingt nach Stapelkorruption für mich. Mein Lieblingswerkzeug, um diese zu finden, ist IDA Pro . Natürlich haben Sie keinen Zugriff auf den Computer des Benutzers.

Einige Speicher-Checker haben es schwer, Stack-Korruption zu finden (wenn es das tatsächlich ist). Der sicherste Weg, um diejenigen zu bekommen, die ich denke, ist die Laufzeitanalyse.

Dies kann auch auf eine Beschädigung in einem Ausnahmepfad zurückzuführen sein, selbst wenn die Ausnahme behandelt wurde. Debuggen Sie mit "Erste-Chance-Ausnahmen fangen" aktiviert? Sie sollten so lange wie möglich. In vielen Fällen wird es nach einer Weile nervig.

Können Sie diesen Benutzern eine überprüfte Version Ihrer Anwendung senden? Check out Minidump Behandle diese Ausnahme und schreibe einen Dump aus. Dann benutze WinDbg , um an deinem Ende zu debuggen.

Eine andere Methode schreibt sehr detaillierte Protokolle. Erstellen Sie eine Option "Jede einzelne Aktion protokollieren", und bitten Sie den Benutzer, diese Option einzuschalten und Ihnen auch zu senden. Speicher für die Protokolle auslagern. Überprüfen Sie '_CrtDbgReport ()' auf MSDN.

Viel Glück!

BEARBEITEN:

Reagieren auf Ihren Kommentar: Ein Fehler bei einer lokalen Variablendeklaration ist für mich nicht überraschend. Ich habe das oft gesehen. Das liegt normalerweise an einem beschädigten Stack.

Eine Variable auf dem Stapel kann zum Beispiel über ihre Grenzen laufen. Danach bricht die Hölle los. Dann werfen Stapelvariablendeklarationen zufällige Speicherfehler, virtuelle Tabellen werden beschädigt usw.

Immer wenn ich diese für eine längere Zeit gesehen habe, musste ich zu IDA Pro gehen. Detailliertes Debugging der Laufzeit-Disassemblierung ist das Einzige, was ich weiß, das diese wirklich zuverlässig macht.

Viele Entwickler verwenden WinDbg für diese Art von Analyse. Deshalb habe ich auch Minidump vorgeschlagen.

    
kervin 25.09.2008 08:46
quelle
1

Probieren Sie Rational (IBM) PurifyPlus aus. Es fängt eine Menge Fehler ab, die BoundsChecker nicht hat.

    
shoosh 25.09.2008 09:08
quelle

Tags und Links