Nur um hinzuzufügen, ich denke, ich habe das gleiche Problem (in einer 64-Bit-C# -Anwendung, die Math.Cos aufruft und zeigt auch ein Flash-Video im .NET Windows Forms WebBrowser-Steuerelement) .
In meinem Fall scheint es, dass der folgende Code in der 64-Bit-Flash-OCX (16.0.0.305) ungültige Werte in den Registern MM0, MM1, MM2, MM3 zurücklässt (dieser Code scheint eine Art von schneller Speicher kopieren):
C:\Windows\System32\Macromed\Flash\Flash64_16_0_0_305.ocx
00000000`2f9833c0 48894c2408 mov qword ptr [rsp+8],rcx
00000000`2f9833c5 4889542410 mov qword ptr [rsp+10h],rdx
00000000`2f9833ca 4c89442418 mov qword ptr [rsp+18h],r8
00000000`2f9833cf 56 push rsi
00000000`2f9833d0 57 push rdi
00000000`2f9833d1 53 push rbx
00000000`2f9833d2 488b7c2420 mov rdi,qword ptr [rsp+20h]
00000000`2f9833d7 488b742428 mov rsi,qword ptr [rsp+28h]
00000000`2f9833dc 488b4c2430 mov rcx,qword ptr [rsp+30h]
00000000`2f9833e1 4881f920000000 cmp rcx,20h
00000000`2f9833e8 7e43 jle Flash64_16_0_0_305!DllUnregisterServer+0x3c2a2d (00000000`2f98342d)
00000000`2f9833ea 4881e920000000 sub rcx,20h
00000000`2f9833f1 0f6f06 movq mm0,mmword ptr [rsi]
00000000`2f9833f4 0f6f4e08 movq mm1,mmword ptr [rsi+8]
00000000`2f9833f8 0f6f5610 movq mm2,mmword ptr [rsi+10h]
00000000`2f9833fc 0f6f5e18 movq mm3,mmword ptr [rsi+18h]
00000000`2f983400 4881c620000000 add rsi,20h
00000000`2f983407 0f7f07 movq mmword ptr [rdi],mm0
00000000`2f98340a 0f7f4f08 movq mmword ptr [rdi+8],mm1
00000000`2f98340e 0f7f5710 movq mmword ptr [rdi+10h],mm2
00000000`2f983412 0f7f5f18 movq mmword ptr [rdi+18h],mm3
00000000`2f983416 4881c720000000 add rdi,20h
00000000`2f98341d 4881e920000000 sub rcx,20h
00000000`2f983424 7dcb jge Flash64_16_0_0_305!DllUnregisterServer+0x3c29f1 (00000000`2f9833f1)
00000000`2f983426 4881c120000000 add rcx,20h
00000000`2f98342d f3a4 rep movs byte ptr [rdi],byte ptr [rsi]
00000000`2f98342f 5b pop rbx
00000000`2f983430 5f pop rdi
00000000`2f983431 5e pop rsi
00000000`2f983432 c3 ret
der obige Code in dem Flash-OCX ausgeführt wird, wie der Web-Browser von der Seite zeigt das Flash-Video navigiert.
Bevor dieser Code die Gleitkomma ausführt wie folgt waren Registern (untersucht unter Verwendung von WinDbg.exe):
fpcw=027f fpsw=3820 fptw=0080
st0= 6.00000000000000000000000...0e+0001 (0:4004:f000000000000000)
st1= 0.00000000000000000000000...0e+0000 (0:0000:0000000000000000)
st2= 0.00000000000000000000000...0e+0000 (0:0000:0000000000000000)
st3= 0.00000000000000000000000...0e+0000 (0:0000:0000000000000000)
st4= 0.00000000000000000000000...0e+0000 (0:0000:0000000000000000)
st5= 1.00000000000000000000000...0e+0000 (0:3fff:8000000000000000)
st6= 8.94231504669236176852000...0e-0001 (0:3ffe:e4ec5b1b9b742000)
st7= 0.00000000000000000000000...0e+0000 (0:0000:0000000000000000)
mxcsr=00001fa4
Nachdem der obige Code die Gleitkommaregister waren wie folgt ausgeführt wurde:
fpcw=027f fpsw=0020 fptw=00ff
st0=-1.#SNAN000000000000000000...0e+0000 (1:7fff:0000000000000000)
st1=-1.#SNAN000000000000000000...0e+0000 (1:7fff:0000000000000000)
st2=-1.#SNAN000000000000000000...0e+0000 (1:7fff:0000000000000000)
st3=-1.#SNAN000000000000000000...0e+0000 (1:7fff:0000000000000000)
st4= 1.00000000000000000000000...0e+0000 (0:3fff:8000000000000000)
st5= 8.94231504669236176852000...0e-0001 (0:3ffe:e4ec5b1b9b742000)
st6= 0.00000000000000000000000...0e+0000 (0:0000:0000000000000000)
st7= 6.00000000000000000000000...0e+0001 (0:4004:f000000000000000)
mxcsr=00001fa4
An diesem Punkt scheinen die Fließkomma-Register in einem "korrupten" Zustand zu sein.
So später wieder in dem C# Programm, wenn die Math.cos FLD opcode Ausführen fehlschlägt, wie es versucht, den Wert 2,0 auf den Gleitkomma-Stapel zu drücken (dh., Wie es für die Berechnung des Kosinus von 2,0 herzustellen versucht)
COMDouble::Cos:
000007FE`E1D01570 movsd mmword ptr [rsp+8],xmm0
000007FE`E1D01576 fld qword ptr [rsp+8]
000007FE`E1D0157A fcos
000007FE`E1D0157C fstp qword ptr [rsp+8]
000007FE`E1D01580 movsd xmm0,mmword ptr [rsp+8]
000007FE`E1D01586 ret
Unmittelbar vor der FLD Opcode die Gleitkommaregister waren genau ausgeführt wird, wie sie durch den Flash-OCX gelassen wurden: (dh wie oben.):
fpcw=027f fpsw=0020 fptw=00ff
st0=-1.#SNAN000000000000000000...0e+0000 (1:7fff:0000000000000000)
st1=-1.#SNAN000000000000000000...0e+0000 (1:7fff:0000000000000000)
st2=-1.#SNAN000000000000000000...0e+0000 (1:7fff:0000000000000000)
st3=-1.#SNAN000000000000000000...0e+0000 (1:7fff:0000000000000000)
st4= 1.00000000000000000000000...0e+0000 (0:3fff:8000000000000000)
st5= 8.94231504669236176852000...0e-0001 (0:3ffe:e4ec5b1b9b742000)
st6= 0.00000000000000000000000...0e+0000 (0:0000:0000000000000000)
st7= 6.00000000000000000000000...0e+0001 (0:4004:f000000000000000)
mxcsr=00001fa4
Unmittelbar nach dem FLD Opcode ausgeführt wurde Fließkommaregister waren wie folgt (notic e dass ST0 ist #IND eher als der erwartete Wert von 2,00000000000000000000000 0E ... + 0000):
fpcw=027f fpsw=3a61 fptw=00ff
st0=-1.#IND0000000000000000000...0e+0000 (1:7fff:c000000000000000)
st1=-1.#SNAN000000000000000000...0e+0000 (1:7fff:0000000000000000)
st2=-1.#SNAN000000000000000000...0e+0000 (1:7fff:0000000000000000)
st3=-1.#SNAN000000000000000000...0e+0000 (1:7fff:0000000000000000)
st4=-1.#SNAN000000000000000000...0e+0000 (1:7fff:0000000000000000)
st5= 1.00000000000000000000000...0e+0000 (0:3fff:8000000000000000)
st6= 8.94231504669236176852000...0e-0001 (0:3ffe:e4ec5b1b9b742000)
st7= 0.00000000000000000000000...0e+0000 (0:0000:0000000000000000)
mxcsr=00001fa4
Das bedeutet dann, dass der EKAS Opcode den Kosinus #IND zu berechnen versucht. Und so endet es, dass der Rückgabewert von Math.Cos in C# Double.NaN statt der erwarteten -0.416146836547142 ist.
Zergliedern des Gleitkomma-Statuswortes (FPSW) -Wert von 0x3a61 zeigt oben, dass das Problem „ein Versuch, einen Wert in ein Register zu laden, die nicht frei ist“:
3a61: 0011 1010 0110 0001
TOP (13,12,11): 111
C3,C2,C1,C0 (14,10,9,8): 0 010 (ie. C1 is 1) <-- loading a value into a register which is not free
IR (7): 0 Interrupt Request
SF (6): 1 Stack Fault <-- loading a value into a register which is not free
P (5): 1 Precision
U (4): 0 Underflow
O (3): 0 Overflow
Z (2): 0 Zero Divide
D (1): 0 Denormalised
I (0): 1 Invalid Operation
zu beachten, dass das Problem nur passiert das erste Mal, dass Math.Cos (2) versucht wird (dh kurz nach der Navigation weg von der Flash-Video-Seite). Der zweite und nachfolgende Versuche, Math.Cos (2) zu berechnen, sind erfolgreich.
Das Problem tritt auch auf, wenn das WebBrowser-Steuerelement verworfen wird, während ein Flash-Video abgespielt wird (oder pausiert).
So einige mögliche Abhilfen sind:
Führen Sie eine Dummy-mathematische Berechnung und das Ergebnis ignorieren.
Schreiben Sie eine 64-Bit-DLL, die eine Funktion exportiert, die die finit- oder emms-Opcodes ausführt (um den Zustand der Gleitkommaregister zurückzusetzen). Nennen Sie diese Funktion von C#.
Ausführen als ein 32-Bit-Prozess.
Hinweis: eine Dummy-Ausnahme in C# zu werfen und dann diese Ausnahme abfangen helfen nicht (dies für andere Gleitkomma Korruption Probleme vorgeschlagen wird).
Hier ist ein C# -Code, der das Problem reproduziert (stellen Sie sicher, dass es kompiliert und als 64-Bit ausgeführt wird; klicken Sie auf die Schaltfläche Berechnen, nachdem das Video abgespielt wurde).
using System;
using System.IO;
using System.Windows.Forms;
namespace FlashTest
{
public partial class TestForm : Form
{
public TestForm()
{
// Windows 7 SP1 64 bit
// Internet Explorer 11 (11.0.9600.17633)
// Flash Player 16.0.0.305
// Visual Studio 2013 (12.0.31101.00)
// .NET 4.5 (4.0.30319.34209)
InitializeComponent();
addressTextBox.Text = "http://www.youtube.com/v/JVGdyC9CvFQ?autoplay=1";
GoButtonClickHandler(this, EventArgs.Empty);
}
private void GoButtonClickHandler(object sender, EventArgs e)
{
string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + ".html");
File.WriteAllText(path, string.Format(@"<html><body>
<object classid=""clsid:D27CDB6E-AE6D-11CF-96B8-444553540000"" width=""100%"" height=""100%"" id=""youtubeviewer"">
<param name=""movie"" value=""{0}"">
</object></body></html>", addressTextBox.Text));
webBrowser.Navigate(path);
}
private void CalculateButtonClickHandler(object sender, EventArgs e)
{
webBrowser.DocumentCompleted += DocumentCompletedHandler;
webBrowser.Navigate("about:blank");
}
private void DocumentCompletedHandler(object sender, WebBrowserDocumentCompletedEventArgs e)
{
webBrowser.DocumentCompleted -= DocumentCompletedHandler;
MessageBox.Show("Math.Cos(2) returned " + Math.Cos(2));
}
}
}
namespace FlashTest
{
partial class TestForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.webBrowser = new System.Windows.Forms.WebBrowser();
this.addressTextBox = new System.Windows.Forms.TextBox();
this.goButton = new System.Windows.Forms.Button();
this.calculateButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// webBrowser
//
this.webBrowser.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.webBrowser.Location = new System.Drawing.Point(12, 41);
this.webBrowser.MinimumSize = new System.Drawing.Size(20, 20);
this.webBrowser.Name = "webBrowser";
this.webBrowser.Size = new System.Drawing.Size(560, 309);
this.webBrowser.TabIndex = 3;
//
// addressTextBox
//
this.addressTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.addressTextBox.Location = new System.Drawing.Point(12, 14);
this.addressTextBox.Name = "addressTextBox";
this.addressTextBox.Size = new System.Drawing.Size(398, 20);
this.addressTextBox.TabIndex = 0;
//
// goButton
//
this.goButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.goButton.Location = new System.Drawing.Point(416, 12);
this.goButton.Name = "goButton";
this.goButton.Size = new System.Drawing.Size(75, 23);
this.goButton.TabIndex = 1;
this.goButton.Text = "&Go";
this.goButton.UseVisualStyleBackColor = true;
this.goButton.Click += new System.EventHandler(this.GoButtonClickHandler);
//
// calculateButton
//
this.calculateButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.calculateButton.Location = new System.Drawing.Point(497, 12);
this.calculateButton.Name = "calculateButton";
this.calculateButton.Size = new System.Drawing.Size(75, 23);
this.calculateButton.TabIndex = 2;
this.calculateButton.Text = "&Calculate";
this.calculateButton.UseVisualStyleBackColor = true;
this.calculateButton.Click += new System.EventHandler(this.CalculateButtonClickHandler);
//
// TestForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(584, 362);
this.Controls.Add(this.webBrowser);
this.Controls.Add(this.goButton);
this.Controls.Add(this.addressTextBox);
this.Controls.Add(this.calculateButton);
this.Name = "TestForm";
this.Text = "Adobe Flash Test";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.WebBrowser webBrowser;
private System.Windows.Forms.TextBox addressTextBox;
private System.Windows.Forms.Button goButton;
private System.Windows.Forms.Button calculateButton;
}
}
Bitte fügen Sie Code für das Problem zu reproduzieren. Wie denkst du, interferiert webkit mit der pow() - Funktion? –
@ sebastian-lang Es stört irgendwie. Schau mal hier: [Screenshot] (http://i.imgur.com/FuquLxN.png) Ich fand heraus, dass nur der erste Aufruf von pow falsches Ergebnis zurückgibt. Auch ich werde mein Bestes tun, um ein funktionierendes Beispiel zu machen, weil es Tausende von Codezeilen in der realen Anwendung gibt. – Ezee
@Ezee Ihre Schritte zum Reproduzieren sind ein Screenshot von zwei Codezeilen in XCode? Sie verstehen völlig falsch, wofür diese sind. Wir glauben Dir. Wir wollen nicht beweisen, dass es passiert. Wir müssen das Problem wiederholen, um Ihnen die richtige Erklärung zu geben. Wie sollen wir von einem Screenshot mit zwei Zeilen Code dorthin gehen? (Beachten Sie, dass "wir" StackOverflow ist, nicht ich insbesondere.) –