2012-02-27 25 views
11

sto ospitando Internet Explorer in un'applicazione Windows. posso scorrere fino alla fine del documento. Quando ho quindi provare a scorrere indietro fino ottengo una divisione per eccezione allo zero:Come eseguire il debug di una divisione con l'eccezione zero in Internet Explorer?

enter image description here

Quando ho scorrere con Page Up l'incidente sembra accadere alla chiamata a - IOleInPlaceActiveObject:TranslateAccelerator

Quando si scorre usando il mouse, l'arresto si verifica durante la chiamata a

In entrambi i casi, l'arresto anomalo si verifica in Internet Explorer.

La traccia pila dimostrato da Delphi al momento eccezione:

enter image description here

è differente dalla traccia dello stack dimostrato da eccezione tracciamento Jedi:

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 

ho provato debugging l'arresto in 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) 

Ma poiché Delphi riesce a catturare tutte le eccezioni, non porge mai sottosopra e interrompe WinDbg. (O forse è per questo che WinDbg non si rompe).

Come posso impedire a Delphi di rilevare eccezioni, in modo che all'applicazione venga consentito il crash anomalo, così posso ottenere le istruzioni che causano il problema. È un'eccezione a virgola mobile, da qualche parte è il codice che tenta di dividere per zero.


Qualcun altro è sempre lo stesso incidente nelle stesse circostanze:

Con i suggerimenti utili da Microsoft che spegnere Ne conosci qualcuno 3rd party, e provare a eseguire IE in modalità provvisoria.

Mentre è bello essere confermato che non sono l'unico a sperimentare questo problema; Sono più interessato a una soluzione.


Le eccezioni possono essere mascherati ponendo l'unità in virgola mobile non sollevare eccezioni, andando a toccare la parola di comando in virgola mobile con l'istruzione 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) 
    } 

Ancora, vorrei per sapere come posso trovare la riga che sta lanciando l'eccezione.

+2

Penso che questo sia semplicemente il problema classico: è necessario impostare la parola di controllo (Set8087CW). –

+0

@AndreasRejbrand È qualcosa che tutte le applicazioni dovrebbero sempre accendere sempre? O è qualcosa che dovrebbe essere attivato e disattivato solo per mascherare l'eccezione che sto ottenendo? (cioè se lo accendo solo per nascondere questa eccezione su questo modulo non so quanto altro codice che non è mio andrà ancora in crash) E se è qualcosa che ogni programma dovrebbe sempre accendere, allora perché dovrebbe essere spento di default? –

+0

Quando si utilizzano controlli ActiveX complessi o qualsiasi DLL esterna, è sempre consigliabile considerarlo. –

risposta

5

Per ottenere la riga di codice che genera l'eccezione, è necessario chiedere a Microsoft l'origine per mshtml.dll. Ecco dove viene generata l'eccezione, dall'istruzione all'indirizzo 00378B89.

Si potrebbe provare ad aprire la finestra della CPU e guardare il codice della macchina dalla DLL, ma se non si è già in grado di eseguire il debug del codice della macchina di qualcun altro, non so quanto possa fare.

La traccia dello stack del debugger e la traccia dello stack JCL sembrano molto simili a me. La differenza principale è che il JCL tenta di fornire alcune informazioni sulla funzione DLL e il debugger no. Non fa molta differenza, però; le informazioni che il JCL mostra sono insignificanti poiché il nome della funzione più vicina che trova è quasi un megabyte lontano dalle effettive istruzioni di errore. L'altra differenza è se TWinControl.MainWndProc è incluso nello stack trace, che a mio avviso è dovuto al fatto che la traccia dello stack sia stata determinata leggendo le informazioni di debug DCU o analizzando il contenuto fisico dello stack.

+0

speravo di capire come fare in modo che il debugger di Delphi si fermasse sulla riga di codice (finestra cpu, riga del codice assembly) che genera l'eccezione. Ho il server Microsoft Symbol e un debugger che può interrogarlo (WinDbg). Ma per qualche motivo l'eccezione non è "vista" fino a quando non è tornata nel mio modulo (forse è una cosa di interoperabilità di COM safecall - ma quindi sarebbe un 'EOleSysError' e non un' EZeroDivide'. –

+0

suppongo che il meglio che farò essere in grado di ottenere è di caricare 'DbgHelp.dll' me stesso, e chiamare l'esportazione che ottiene informazioni sui simboli per offset' 00378B89'. Se vado in giro a scrivere le importazioni di DbgHelp pubblicherò i miei risultati –

0

Se non si utilizza Math.SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]), la correzione funziona solo su 64 bit Windows.

+0

Bene, la domanda era per Delphi 5 quindi è discutibile e suppongo che intendessi solo lavori a 32 bit, non a 64 bit. –