2010-04-13 10 views
7

Der folgende Code gibt nicht eine harte, wenn sie unter Windows 7 32bit laufen:64bit Ausnahmen in WndProc nicht still

void CTestView::OnDraw(CDC* /*pDC*/) 
{ 
    *(int*)0 = 0; // Crash 

    CTestDoc* pDoc = GetDocument(); 
    ASSERT_VALID(pDoc); 
    if (!pDoc) 
     return; 

    // TODO: add draw code for native data here 
} 

Allerdings, wenn ich versuchen, diese auf Windows 7 64bit, bekomme ich das nur im Ausgabefenster :

Erste-Chance-Ausnahme bei 0x13929384 in Test.exe: 0xC0000005: Zugriffs Verletzung Schreibort 0x00000000.
erste Chance Ausnahme bei 0x77c6ee42 in Test.exe: 0xC0150010: Der Aktivierungskontext deaktiviert wird für den aktuellen Thread der Ausführung nicht aktiv ist.

Was ist der Grund dafür? Ich weiß, es ist eine Hardware-Ausnahme (http://msdn.microsoft.com/en-us/library/aa363082.aspx), aber warum der Unterschied, wenn unter 32bit und 64bit lief? Und was kann ich tun, um diese Art von Fehlern richtig zu behandeln? Weil sie wirklich gefangen und repariert werden sollten, im Gegensatz zu dem, was momentan passiert, das Windows nur weiter Nachrichten an die Anwendung pumpt und es laufen lässt (so dass der Benutzer und die Entwickler sich völlig nicht bewusst sind, dass irgendwelche Probleme tatsächlich aufgetreten sind).

Update: Unsere regelmäßige Crash-Reporting-Software verwendet SetUnhandledExceptionFilter aber nicht auf x64 für Hardware-Ausnahmen in einer WndProc genannt bekommt. Hat jemand irgendwelche Informationen dazu oder einen Workaround?

Update2: ich das Problem bei Microsoft Connect berichtet haben:
https://connect.microsoft.com/VisualStudio/feedback/details/550944/hardware-exceptions-on-x64-machines-are-silently-caught-in-wndproc-messages

+0

Ich nehme nicht nur für 64-Bit-Kompilierung eine Option? – jalf

+0

Kompilieren für x64 ist nicht wirklich eine Option, unser Quellcode besteht aus ungefähr 1 Millionen Zeilen Code, mit einer beträchtlichen Menge an Assembler. Kombinieren Sie das mit den zusätzlichen Kosten für die Ausführung von zwei separaten Builds über QA usw. –

+1

Siehe auch den Abschnitt Anmerkungen von [WindowProc Callback-Funktion] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633573% 28v = vs.85% 29.aspx) – wimh

Antwort

1

OK, ich habe eine Antwort von Microsoft erhalten:

Hallo,

Dank für den Bericht. Ich habe herausgefunden, , dass dies ein Windows-Problem ist, und gibt es eine Hotfix verfügbar. Bitte siehe http://support.microsoft.com/kb/976038 für eine Reparatur, die Sie installieren können, wenn Sie wünschen.

@Skute: beachten Sie, dass das Programm Compatibility Assistant einmal fragen , wenn das Programm erlaubt werden soll, um auszuführen fortzusetzen und nach, dass es immer erlaubt werden, so dass die Ursache für die verwirrend sein kann Verhalten Sie sehen.

Pat Brenner Visual C++ Bibliotheken Entwicklung

So ist die Abhilfe entweder sicherstellen, dass der Hotfix installiert ist, oder wickeln Sie jede WndProc in Ihrer Anwendung mit einem __try/__except Block.

+0

Können Sie weitere Informationen angeben, wo Sie __try __except verwenden? Ist es sogar möglich, Ausnahme von WindowProc in Catch-Block in C++ - Anwendung zu fangen. Über Hotfix Ich setze DisableUserModeCallbackFilter auf 1 in der Registrierung und am besten bekomme ich FATAL_USER_CALLBACK_EXCEPTION, nicht meine Ausnahme. – Demion

+0

Sie verwenden '__try'' __except' in Ihrer 'WNDPROC'Funktion, oder wenn Sie MFC verwenden, wäre das die' CWnd :: OnMsg' Funktion (ich denke, das ist verrückt, vielleicht falsch) . –

+0

Ist es möglich, Ausnahme von WindowProc zu werfen, in WindowProc nicht zu fangen? – Demion

3

Es gibt eine weitere Ausnahme ausgelöst wird, während der Stapel abgewickelt für die Zugriffsverletzung Ausnahme. Das wird verschluckt, wodurch der AV verschwindet. Sie müssen herausfinden, welcher Code das tut. Debug + Exceptions, aktivieren Sie die Box "Geworfen" für Win32-Ausnahmen. Der Debugger stoppt auf dem ersten, weiter. Überprüfen Sie die Anrufliste, wenn sie erneut anhält. Fügen Sie es Ihrer Frage hinzu, wenn Sie es nicht herausfinden können.

+1

Die Aktivierungskontextausnahme tritt nur auf, wenn die AV-Ausnahme ausgelöst wird. –

0

Die einzige Möglichkeit, dieses Problem zu umgehen, besteht darin, ein __try/__except um jeden WndProc-Callback in der Anwendung zu setzen. Wir leiten dann die Ausnahme an unseren Ausnahme-Handler weiter. Schrecklich, aber sieht aus wie es ein Problem mit Windows selbst ist. Ich warte immer noch auf Microsoft, um zu uns zurück zu kommen.

0

Ich würde vermuten, dass das Problem tatsächlich damit zusammenhängt, wie SEH in x64 funktioniert. Wenn Ihre Ausnahmebedingung während des Abwickelns des Stacks durch den Kernel-Modus zurückgehen muss, dann ist das, was Sie merken, das Design-Verhalten: The case of the disappearing OnLoad exception. Windows "verarbeitet" Ihre Ausnahme für Sie; Der Hot-Fix ist ein Workaround, um bestimmte x64-Apps zum Absturz zu bringen, genau wie x86.

0

Ich habe einige Hausaufgaben gemacht, um dies zu finden: die Ausnahme wird von Windows abgefangen. Hier sind Stapeln und Auseinanderbauen:

stack and disassembling when wndproc get called