Как отладить деление на ноль исключений в Internet Explorer? - PullRequest
11 голосов
/ 28 февраля 2012

Я размещаю Internet Explorer в приложении Windows.я могу прокрутить вниз до нижней части документа.Когда я затем пытаюсь прокрутить назад, я получаю деление на ноль исключений :

enter image description here

Когда я прокручиваю, используя Page Up сбой, кажется, происходит при вызове - IOleInPlaceActiveObject:TranslateAccelerator

При прокрутке с помощью мыши происходит сбой при вызове

В любом случае происходит сбой в Internet Explorer.

Трассировка стека , показанная Delphi ввремя исключения:

enter image description here

Отличается от трассировки стека, показанной трассировкой исключений джедая:

Exception EZeroDivide in module mshtml.dll at 00378B89.
Floating point division by zero.

Exception raised by object: TEmbeddedWB


Full Exception Details:
EZeroDivide
ExceptionCode: 0xC000008E (EXCEPTION_FLT_DIVIDE_BY_ZERO)
The thread tried to divide a floating-point value by a floating-point divisor of zero.
ExceptionFlags: 0x00000002
ExceptionAddress: 0x574C8B89
Parameters: (0x00000000)
EXCEPTION_RECORD: nil
Message: Floating point division by zero


Stack Trace:
[574C8B89] Unknown function at DllGetClassObject + $FF033
[004CA61E] OleCtrls.TOleControl.WndProc (Line 2171, "olectrls.pas" + 12) + $10
[006CF62A] EmbeddedWB.TEmbeddedWB.WBWndProc (Line 1492, "EmbeddedWB.pas" + 31) + $8
[0046200C] Forms.StdWndProc (Line 1459, "Forms.pas" + 8) + $0
[0046D2A2] Forms.TApplication.IsKeyMsg (Line 6588, "Forms.pas" + 20) + $1E
[0046D43F] Forms.TApplication.ProcessMessage (Line 6626, "Forms.pas" + 9) + $2A
[0046D4AB] Forms.TApplication.HandleMessage (Line 6649, "Forms.pas" + 1) + $6
[0046938C] Forms.TCustomForm.ShowModal (Line 4692, "Forms.pas" + 22) + $5
[007D72AD] FMain.TfrmMain.actControlPanelExecute (Line 566, "FMain.pas" + 5) + $5
[00424AF5] Classes.TBasicAction.Execute (Line 8077, "Classes.pas" + 3) + $9
[00455369] ActnList.TContainedAction.Execute + $31
[0045B6AE] Menus.TMenuItem.Click (Line 1738, "Menus.pas" + 9) + $8
[0045CD71] Menus.TMenu.DispatchCommand (Line 2446, "Menus.pas" + 5) + $5

Я попытался отладить сбой в WinDbg:

ModLoad: 00000000`75360000 00000000`75372000   C:\Windows\syswow64\DEVOBJ.dll
ModLoad: 00000000`71940000 00000000`719fa000   C:\Windows\SysWOW64\d2d1.dll
ModLoad: 00000000`715e0000 00000000`716ea000   C:\Windows\SysWOW64\DWrite.dll
ModLoad: 00000000`71870000 00000000`718f3000   C:\Windows\SysWOW64\dxgi.dll
ModLoad: 00000000`74fb0000 00000000`74fdd000   C:\Windows\syswow64\WINTRUST.dll
ModLoad: 00000000`71db0000 00000000`71ddc000   C:\Windows\SysWOW64\d3d10_1.dll
ModLoad: 00000000`71900000 00000000`7193a000   C:\Windows\SysWOW64\d3d10_1core.dll
ModLoad: 00000000`6e5c0000 00000000`6e6ec000   C:\Windows\SysWOW64\D3D10Warp.dll
ModLoad: 00000000`6d480000 00000000`6d63b000   C:\Windows\SysWOW64\jscript9.dll
ModLoad: 00000000`714f0000 00000000`714fb000   C:\Windows\SysWOW64\msimtf.dll
ModLoad: 00000000`6f080000 00000000`6f0ab000   C:\Windows\SysWOW64\msls31.dll
ModLoad: 00000000`082c0000 00000000`082fc000   C:\Windows\SysWOW64\Oleacc.dll
ModLoad: 00000000`613e0000 00000000`6140e000   C:\Windows\SysWOW64\MLANG.dll
ModLoad: 00000000`62bb0000 00000000`62cb2000   C:\Windows\SysWOW64\d3d10.dll
ModLoad: 00000000`62b70000 00000000`62ba3000   C:\Windows\SysWOW64\d3d10core.dll
(834.d04): Unknown exception - code c000008e (first chance)

Но поскольку Delphi перехватывает все исключения, он никогда не высовывается и не ломает WinDbg.(Или, может быть, поэтому WinDbg не ломается).

Как я могу остановить Delphi от перехвата исключений, чтобы приложение могло аварийно завершить работу, чтобы я мог получить инструкцию, которая вызывает проблему.Это исключение с плавающей запятой, где-то - это код, который пытается разделить на ноль.


Кто-то другой получает ту же ошибку в тех же обстоятельствах:

С полезными советами от Microsoft, чтобы он отключил любую стороннюю компаниюаддоны и попробуйте запустить IE в безопасном режиме.

Хотя приятно быть подтвержденным, что я не единственный, кто испытывает эту проблему;меня больше интересует решение.


Исключения могут быть замаскированы , если попросить единицу с плавающей запятой не вызывать исключения, перебрав управляющее слово с плавающей запятой с помощью FLDCW инструкция:

procedure TfrmControlPanel.FormCreate(Sender: TObject);
begin
FSaved8087CW := Default8087CW;  // Save this because Set8087CW changes it.
Set8087CW($027F); //restore later using Set8087CW(FSaved8087CW);
       //$027F comes from http://msdn.microsoft.com/en-us/library/ms235300.aspx  

   {
      Scrolling in browser was causing floating point exceptions

      http://stackoverflow.com/questions/9472265/how-to-debug-division-by-zero-exception-in-internet-explorer

      What it boils down to is that MS habitually compile their code with FP exceptions masked.
      Embarcadero tools habitually unmask them. Thus the MS code is written assuming that FP exceptions
      will not be raised and is not resilient to them. To deal with that you have to mask the exceptions
      before calling into the MS code. If your app does not floating point then just mask the exceptions
      at start up and be done with it. Call Set8087CW($027F) at start up and you are good to go.

            Default8087CW: $1332  = 0001 0011 0011 0010
            New 8087CW:    $027F  = 0000 0010 0111 1111
                                    ...I RCPC ..MM MMMM

        Bit  0: Invalid Operation (IM)  |
        Bit  1: Denormal Operand (DM)   |
        Bit  2: Zero Divide (ZM)        | Exception Masks (Bits 0..5)
        Bit  3: Overflow (OM)           | When one of these mask bits is set, its corresponding x87 FPU
        Bit  4: Underflow (UM)          | floating-point exception is blocked from being generated
        Bit  5: Precision (PM)          |
        Bit  6:  (reserved)
        Bit  7:  (reserved)
        Bit  8: +Precision Control (PC) 00=Single Precision (24 bits), 10=Double Precision (53 bits), 11=Double Extended Precision (64 bits), 01=reserved
        Bit  9: /
        Bit 10: + Rounding Control (RC)
        Bit 11: /
        Bit 12: Infinity Control        | not meaningful for anything past the 80287 math coprocessor
        Bit 13:  (reserved)
        Bit 14:  (reserved)
        Bit 15:  (reserved)
    }

Тем не менее, я хотел бы знать, как найти строку , которая вызывает исключение.

Ответы [ 2 ]

5 голосов
/ 28 февраля 2012

Чтобы получить строку кода, которая выдает исключение, вам нужно будет запросить у Microsoft источник mshtml.dll . Вот где выдается исключение по инструкции по адресу 00378B89.

Вы можете попробовать открыть окно ЦП и посмотреть на машинный код из DLL, но если вам пока не удобно отлаживать чужой машинный код, я не знаю, насколько он вам пригодится.

Трассировка стека отладчика и трассировка стека JCL очень похожи на меня. Основное отличие состоит в том, что JCL пытается дать некоторую информацию о функции DLL, а отладчик - нет. Это не большая разница, хотя; информация, которую показывает JCL, не имеет смысла, так как ближайшее имя функции, которое он находит, находится на расстоянии почти мегабайта от действительной ошибочной инструкции. Другое отличие состоит в том, включен ли TWinControl.MainWndProc в трассировку стека, что, как я подозреваю, связано с тем, была ли трассировка стека определена путем чтения отладочной информации DCU или путем анализа физического содержимого стека.

0 голосов
/ 06 марта 2013

Если вы не используете Math.SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]), исправление работает только на 64-битной Windows .

...