TWebBrowser crashes with embedded Youtube clips
Asked Answered
E

2

5

Here is my code:

type
  TForm1 = class(TForm)
    WebBrowser1: TWebBrowser;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  end;

implementation
uses ActiveX;

procedure TForm1.Button1Click(Sender: TObject); // method 1
var
  HtmlFile: string;
begin
  HtmlFile := ExtractFilePath(Application.ExeName) + 'test.html';
  WebBrowser1.Navigate(HtmlFile);
end;

procedure LoadHtml(wb: TWebBrowser; HTMLStr: string);
var
  aStream: TMemoryStream;
begin
  wb.Navigate('about:blank'); // reset the webbrowser
  while wb.ReadyState < READYSTATE_INTERACTIVE do // wait to load the empty page
    Application.ProcessMessages;
  if Assigned(wb.Document) then
  begin
    aStream := TMemoryStream.Create;
    try
      aStream.WriteBuffer(Pointer(HTMLStr)^, Length(HTMLStr));
      aStream.Seek(0, soFromBeginning);
      (wb.Document as IPersistStreamInit).Load(TStreamAdapter.Create(aStream));
    finally
      aStream.Free;
    end;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject); // method 2
begin
  LoadHtml(WebBrowser1,
    '<html><head></head><body>'+
    '  <object width="640" height="390"> '+
    '  <param name="movie" value="http://www.youtube.com/v/L7NWdxFAHdY&hl=en_US&feature=player_embedded&version=3"> '+
    '  </param><param name="allowFullScreen" value="true"> '+
    '  </param><param name="allowScriptAccess" value="always"> '+
    '  </param><embed src="http://www.youtube.com/v/L7NWdxFAHdY&hl=en_US&feature=player_embedded&version=3" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="640" height="390"> '+
    '  </embed></object> '+
    '</body></html>'
    );
end;

test.html

<object width="425" height="349">
<param name="movie" value="http://www.youtube.com/v/1hPxGmTGarM?version=3&amp;hl=iw_IL">
</param><param name="allowFullScreen" value="true"></param>
<param name="allowscriptaccess" value="always"></param>
<embed src="http://www.youtube.com/v/1hPxGmTGarM?version=3&amp;hl=iw_IL" type="application/x-shockwave-flash" width="425" height="349" allowscriptaccess="always" allowfullscreen="true">
</embed></object>

My application crashes in both methods. I get An unhandled win32 exception (caused by Flash player Exception EInvalidOp in module Flash10u.ocx at 00108657. Invalid floating point operation).

  • I tried this code on D5, D7, D9.
  • I tried to re-import SHDocVw.dll.
  • I also tried to use EmbeddedWB control instead of TWebBroser...
  • Internet Explorer/Avant/Maxthon has no problems with this HTML (all based on IE ActiveX).

Any suggestions or a fix?

How can I catch this error or even suppress it?

Is there a way to manipulate or change the HTML on the fly via a TWebBrowser event, so I can display an Image instead of the Flash player, same as Ad-Blockers works? (My customers have that code in their sites over the internet, and my Delphi application provides a fast preview)

UPDATE

I used a TTimer to enable/disable FPU (based on Arjen's idea):

function Get8087CW: Word; // for D5
asm
        PUSH    0
        FNSTCW  [ESP].Word
        POP     EAX
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Timer1.Enabled := False;
  Timer1.Interval := 5000; // 5 sec
  Saved8087CW := Get8087CW;
end;

procedure TForm1.WebBrowser1BeforeNavigate2(Sender: TObject;
  const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
  Headers: OleVariant; var Cancel: WordBool);
begin
  Timer1.Enabled := False;
  System.Set8087CW($133F); // Disable all fpu exceptions
end;

procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
begin
   Timer1.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := False;
  Set8087CW(Saved8087CW);
end;

UPDATE (2)

I ended up masking the FPU exception in the application start-up. there was no (known) impact on my application ever since.

Embarrassment answered 20/11, 2011 at 9:22 Comment(12)
It would if you provide more info about the exception. The exact message, code and line.Brentbrenton
Exception EInvalidOp in module Flash10u.ocx at 00108657. Invalid floating point operation. I have also updated to the latest flash player.Embarrassment
@kobik, Have you tried the embed code with <iframe> ?Interlingua
@TLama, Yes I did, same result. actually, I can't control what code is used by my customers. they embed iframes (it's the code they take from youtube by default), and also embed YouTube old code.Embarrassment
@kobik, I've tried your code with D2009, on Windows XP, IE7 with Flash Player 11.1.102.55 (current version) and it works fine. The solutions provided here are in my view only workarounds suppressing the real problem (IMHO you just need to update the Flash Player; IWebBrowser2 interface used by TWebBrowser is here since Internet Explorer 4.0). But I would suggest you to handle the errors somehow, not to suppress them.Interlingua
@TLama, can you please send me the complied exe project?Embarrassment
@kobik, here it is. But I don't know how this can help you. I bet we have the same IWebBroswer2 implementation so I guess you will get the same error as you got also with this binary (which works for me).Interlingua
@TLama, Thanks a million. as I suspected, I get a Invalid floating point operation. Tested on 2 computers: XP/IE8 and Win7/IE9. both have current Flash Player. Here is a screenshotEmbarrassment
@kobik, what about this or this ?Interlingua
@TLama, Thanks for the info. believe me, I've been there months ago. sadly It does not fix the problem. I cannot depend on Flash updates in order to maintain my application, with thousands of clients. I'm getting more and more sure that FPU is the MAIN issue here.Embarrassment
@kobik, I'm afraid you should depend on Flash (updates) in a way. This is the worse case (exception), but when I tried your code with the configuration I've mentioned before I've been asked for the flash update, but this was impossible to do from a TWebBrowser (I had to open IE and do it there). How would you handle this situation ? I would definitely look for a way how to catch the errors from a TWebBrowser. Also for YouTube player there are events, the onStateChange with video cued state means video is ready.Interlingua
@TLamaת In my specific app, I do not care that my customers can't see the Flash player, if it's not up to date on their PC. they should install Flash updates like you did and maintain their system. what I do care is that my app does not crash. What will happen if you update to IE8/9 and your Flash update will crash? I would love to catch the error form the TWebBrowser, but it can not be done AFIAK. I would definitely prefer catching the exception solution.Embarrassment
H
4

Try to disable temporarily FPU exception with Set8087CW(0x133f); info

Hydrocephalus answered 20/11, 2011 at 10:38 Comment(11)
this method actually works. How safe is it to turn the FPU exception off for my entire application at startup? It seems I can't temporarily disable it, because OnDownloadComplete fires before the clip is loaded. :/Embarrassment
It affects rounding mode, precision and floating point exceptions in the rest of your application. If that's not an issue, turn it off for your entire applicationHydrocephalus
since I don't know what effect the 8087 FPU controller will have on my application (My app uses a lot of arithmetic calculations etc) I do not feel comfortable using it on a global basis yet. it is also suggested from other threads I read, that we need to use ClearPending8087Exceptions (Jcl8087) when finalizing our app. I will investigate this more...Embarrassment
OnDownloadComplete fires multiple times! Use OnBeforeNavigate2 (start) and OnDocumentComplete (finish) to set and reset 8087CW.Hydrocephalus
My mistake in the first comment. I DO use OnBeforeNavigate2 and OnDocumentComplete. problem is that `OnDocumentComplete' fires too early! Can you test my demo project?Embarrassment
I try but was not able to see content, probably because of security settings.Hydrocephalus
@Embarrassment Are you sure that you are using a web brower showing You Tube clips, and floating point arithmetic in the same app. Sounds highly unlikely. Tell us about the FP arithmetic. My instincts say that you are safe to mask exceptions.Shizukoshizuoka
@kobic, Exceptions are often result from the lack of bounds checks. I agree with David: I also think its safe to mask exceptions.Hydrocephalus
@DavidHeffernan, it's a large scale content management and e-commerce application, which involves pricing logic, image processing, and much more. the content is dynamic, and the TWebBrowser is used as a preview pane on the main form. IMHO, for now, this problem cannot be solved without disabling FPU exceptions :/ I would be very glad if anyone of you could reproduce this exception also.Embarrassment
I'm quite convinced that FPU excetpions are the issue. I don't know what the threading arrangements are for your app but I wonder if the web browser could be housed in a separate thread which would allow you to isolate the FPU CW changes to that thread.Shizukoshizuoka
I have a similar problem but the browser crashes when it starts loading the file not when it ends: #39594893 Unfortunately, this trick didn't helped me.Bricklayer
G
5

A bit more beautiful solution:

Math.SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow,
  exUnderflow, exPrecision]);

If I read documentation correct, Math.SetExceptionMask silences every exception mentioned.

However, it is just cleaner and more beautiful version of @Arjen's approach.

Gangue answered 20/11, 2011 at 14:45 Comment(4)
I'm using D5 for my application, so Math.SetExceptionMask is not available in D5. I checked D9 sources and the function basically does this: Set8087CW((Get8087CW and $FFC0) or $3F). what bugs me a bit, is that Get8087CW returns $1372 and not $1332. resulting the FPU word to $137F (or maybe I'm just being too pedantic :/ )Embarrassment
@Embarrassment $1332 vs $1372 is just the fact that some CW bits are reserved. Don't worry about that.Shizukoshizuoka
@Embarrassment I think it's "To avoid raising exceptions when changing FPU operating modes" See Intel's doc, page "Vol. 2A 3-385"Gangue
Now in 2019 this solution is preferable, since it works for both 32- and 64-bits programs. While @ArjenvanderSpek 's only works in 32-bits mode.Hornstein
H
4

Try to disable temporarily FPU exception with Set8087CW(0x133f); info

Hydrocephalus answered 20/11, 2011 at 10:38 Comment(11)
this method actually works. How safe is it to turn the FPU exception off for my entire application at startup? It seems I can't temporarily disable it, because OnDownloadComplete fires before the clip is loaded. :/Embarrassment
It affects rounding mode, precision and floating point exceptions in the rest of your application. If that's not an issue, turn it off for your entire applicationHydrocephalus
since I don't know what effect the 8087 FPU controller will have on my application (My app uses a lot of arithmetic calculations etc) I do not feel comfortable using it on a global basis yet. it is also suggested from other threads I read, that we need to use ClearPending8087Exceptions (Jcl8087) when finalizing our app. I will investigate this more...Embarrassment
OnDownloadComplete fires multiple times! Use OnBeforeNavigate2 (start) and OnDocumentComplete (finish) to set and reset 8087CW.Hydrocephalus
My mistake in the first comment. I DO use OnBeforeNavigate2 and OnDocumentComplete. problem is that `OnDocumentComplete' fires too early! Can you test my demo project?Embarrassment
I try but was not able to see content, probably because of security settings.Hydrocephalus
@Embarrassment Are you sure that you are using a web brower showing You Tube clips, and floating point arithmetic in the same app. Sounds highly unlikely. Tell us about the FP arithmetic. My instincts say that you are safe to mask exceptions.Shizukoshizuoka
@kobic, Exceptions are often result from the lack of bounds checks. I agree with David: I also think its safe to mask exceptions.Hydrocephalus
@DavidHeffernan, it's a large scale content management and e-commerce application, which involves pricing logic, image processing, and much more. the content is dynamic, and the TWebBrowser is used as a preview pane on the main form. IMHO, for now, this problem cannot be solved without disabling FPU exceptions :/ I would be very glad if anyone of you could reproduce this exception also.Embarrassment
I'm quite convinced that FPU excetpions are the issue. I don't know what the threading arrangements are for your app but I wonder if the web browser could be housed in a separate thread which would allow you to isolate the FPU CW changes to that thread.Shizukoshizuoka
I have a similar problem but the browser crashes when it starts loading the file not when it ends: #39594893 Unfortunately, this trick didn't helped me.Bricklayer

© 2022 - 2024 — McMap. All rights reserved.