"Dmitry Timoshkov" dmitry@sloboda.ru writes:
Unhandled exception: c000008f [...]
Commenting lines 36-37 physDev->pen.width = GDI_ROUND((FLOAT)pen->logpen.lopnWidth.x * dc->xformWorld2Vport.eM11 * 0.5); in X11DRV_PEN_SelectObject (graphics/x11drv/pen.c) cures the problem.
Why call to floor() leads to crash?
Exception c000008f is EXCEPTION_FLT_INEXACT_RESULT. Probably one of the floating point values is invalid, or something similar.
"Alexandre Julliard" julliard@winehq.com wrote:
Commenting lines 36-37 physDev->pen.width = GDI_ROUND((FLOAT)pen->logpen.lopnWidth.x * dc->xformWorld2Vport.eM11 * 0.5); in X11DRV_PEN_SelectObject (graphics/x11drv/pen.c) cures the problem.
Why call to floor() leads to crash?
Exception c000008f is EXCEPTION_FLT_INEXACT_RESULT. Probably one of the floating point values is invalid, or something similar.
Exception occurs when pen->logpen.lopnWidth.x = 0 and dc->xformWorld2Vport.eM11 = 0.0 It's very strange. Attached patch helps to eliminate crash. But I don't understand where the source of problem.
On Tue, 17 Apr 2001 12:18:12 +0800, you wrote:
"Alexandre Julliard" julliard@winehq.com wrote:
Commenting lines 36-37 physDev->pen.width = GDI_ROUND((FLOAT)pen->logpen.lopnWidth.x * dc->xformWorld2Vport.eM11 * 0.5); in X11DRV_PEN_SelectObject (graphics/x11drv/pen.c) cures the problem.
Why call to floor() leads to crash?
Exception c000008f is EXCEPTION_FLT_INEXACT_RESULT. Probably one of the floating point values is invalid, or something similar.
On the other hand this exception is normally masked, even something as simple as a division of 1.0 by 3.0 can generate it because the result cannot be represented exactly. Also the round-to-int instruction that has just happened here can cause it. So the question would be, why it is not masked?
Exception occurs when pen->logpen.lopnWidth.x = 0 and dc->xformWorld2Vport.eM11 = 0.0 It's very strange. Attached patch helps to eliminate crash. But I don't understand where the source of problem.
| 0x40897fde (X11DRV_PEN_SelectObject+0x8e [pen.c:69]): fldcw 0xfffffffe(%edx)
This instruction loads the control status word with a new value. Bit 5 of the CW (0x20) ,PM Precision Mask , is the mask bit for this exception.
Find out how this bit has become zero (disassembly of the instructions before the crash). If I put a breakpoint on the instruction above, the CW is loaded with 0x37f: all FP exceptions are off.
Rein.
"Rein Klazes" rklazes@xs4all.nl wrote:
Exception occurs when pen->logpen.lopnWidth.x = 0 and dc->xformWorld2Vport.eM11 = 0.0 It's very strange. Attached patch helps to eliminate crash. But I don't understand where the source of problem.
| 0x40897fde (X11DRV_PEN_SelectObject+0x8e [pen.c:69]): fldcw 0xfffffffe(%edx)
This instruction loads the control status word with a new value. Bit 5 of the CW (0x20) ,PM Precision Mask , is the mask bit for this exception.
Find out how this bit has become zero (disassembly of the instructions before the crash). If I put a breakpoint on the instruction above, the CW is loaded with 0x37f: all FP exceptions are off.
I have attached full assembly listing of graphics/x11drv/pen.c produced by gcc. I removed -g option to reduce the output size and added -S -fverbose-asm.
On Wed, 18 Apr 2001 11:54:37 +0800, you wrote:
I have attached full assembly listing of graphics/x11drv/pen.c produced by gcc. I removed -g option to reduce the output size and added -S -fverbose-asm.
Same as the dissassembly that I see here:
| fnstcw -2(%edx)
Store the CW in a temporary variable.
|#NO_APP | movzwl -2(%edx),%eax | andb $243,%ah | orb $4,%ah
This manipulates bits 10 and 11, that control the rounding behaviour.
| movw %ax,-4(%edx) |#APP | fldcw -4(%edx)
Load the CW with adjusted bits 10 and 11.
| frndint
Rounding the float value to int, which likely causes a lost precision exception. Because it does not, the PE mask must be set.
| fldcw -2(%edx)
Load original CW. Now the exception happens, which indicates the PE maskbit is cleared. I don't see how that can be. (you should check that the disassembly in winedbg is the same as this code)
Moreover I cannot reproduce your failure (using gcc 2.95.4 and gnu as 2.11.90.0.1) If I set the variables to 0 and 0.0, no exception follows.
Rein.
"Rein Klazes" rklazes@xs4all.nl wrote:
[...]
| fldcw -2(%edx)
Load original CW. Now the exception happens, which indicates the PE maskbit is cleared. I don't see how that can be. (you should check that the disassembly in winedbg is the same as this code)
Attached disassembly is almost the same as assember generated by gcc (not counting garbage instead of jump table and fildl (gcc) vs. filds (winedbg))
Moreover I cannot reproduce your failure (using gcc 2.95.4 and gnu as 2.11.90.0.1) If I set the variables to 0 and 0.0, no exception follows.
I'm completely at loss now. I'm debugging very complex application which actually consists of several simultaneously running processes. Perhaps interaction between processes leads to some unexpected behaviour.
Also I don't understand why winedbg prints dc->xformWorld2Vport.eM11 = 0.0, though dc->xformWorld2Vport.eM11 is always 1.0 in the log trace (added to X11DRV_PEN_SelectObject right before the GDI_ROUND call).
Something wrong, but I don't know how proceed further yet. Any thoughts?
On Wed, 18 Apr 2001 20:08:12 +0800, you wrote:
"Rein Klazes" rklazes@xs4all.nl wrote:
[...]
| fldcw -2(%edx)
Load original CW. Now the exception happens, which indicates the PE maskbit is cleared. I don't see how that can be. (you should check that the disassembly in winedbg is the same as this code)
Attached disassembly is almost the same as assember generated by gcc (not counting garbage instead of jump table and fildl (gcc) vs. filds (winedbg))
The 8 instructions or so that I quoted would have been enough. And those instructions seem to be assembled OK. Btw did you ever check the value that was loaded in the CW, so the 16 bit value in -2(%edx) ?
Also I don't understand why winedbg prints dc->xformWorld2Vport.eM11 = 0.0, though is always 1.0 in the log trace (added to X11DRV_PEN_SelectObject right before the GDI_ROUND call). Something wrong, but I don't know how proceed further yet. Any thoughts?
I would trust the trace, more then the debugger. Things can be really tricky though with floating points. The only way to be 100% sure is to to show the actual bit pattern. All zero's is 0.0. Anything else is not, but a printf can still print 0.0. If you manage to find how this eM11 is stored in memory (in winedbg with something like x &(dc->xformWorld2Vport.eM11) then I can tell you if there is something wrong with it.
Rein.
"Rein Klazes" rklazes@xs4all.nl wrote:
Attached disassembly is almost the same as assember generated by gcc (not counting garbage instead of jump table and fildl (gcc) vs. filds (winedbg))
The 8 instructions or so that I quoted would have been enough. And those instructions seem to be assembled OK. Btw did you ever check the value that was loaded in the CW, so the 16 bit value in -2(%edx) ?
Do you mean something like that?
Unhandled exception: c000008f in 32-bit code (0x40858a6e). In 32-bit mode. Symbol h_errno is invalid Symbol hack_digit is invalid 0x40858a6e (X11DRV_PEN_SelectObject+0x8e [pen.c:69]): fldcw 0xfffffffe(%edx) 69 } Wine-dbg>info regs info regs Register dump: CS:0023 SS:002b DS:002b ES:002b FS:027f GS:0000 EIP:40858a6e ESP:42005a64 EBP:42005aac EFLAGS:00010202( R- 00 I - - 1 ) EAX:00001640 EBX:4087d00c ECX:4038c7bc EDX:42005a8c ESI:4038c160 EDI:40807054 Wine-dbg>x ($edx-2) x ($edx-2) 70001240 Wine-dbg>
I'm sorry, but At&T syntax is not familiar for me. Floating point assembler instructions either.
Also I don't understand why winedbg prints dc->xformWorld2Vport.eM11 = 0.0, though is always 1.0 in the log trace (added to X11DRV_PEN_SelectObject right before the GDI_ROUND call). Something wrong, but I don't know how proceed further yet. Any thoughts?
I would trust the trace, more then the debugger. Things can be really tricky though with floating points. The only way to be 100% sure is to to show the actual bit pattern. All zero's is 0.0. Anything else is not, but a printf can still print 0.0.
Patch from Eric cured the wine debugger.
On Fri, 20 Apr 2001 16:45:33 +0800, you wrote:
Wine-dbg>info regs info regs Register dump: CS:0023 SS:002b DS:002b ES:002b FS:027f GS:0000 EIP:40858a6e ESP:42005a64 EBP:42005aac EFLAGS:00010202( R- 00 I - - 1 ) EAX:00001640 EBX:4087d00c ECX:4038c7bc EDX:42005a8c ESI:4038c160 EDI:40807054 Wine-dbg>x ($edx-2) x ($edx-2) 70001240
That is what I meant. If I do the same:
|Wine-dbg>x $edx-2 | 7000037f
The lower 6 bits are the new floating point exception masks. Mine are all set and yours are cleared, therefore the crash.
Why that is the case, I haven't got a clue.
Rein.
Also I don't understand why winedbg prints dc->xformWorld2Vport.eM11 = 0.0, though dc->xformWorld2Vport.eM11 is always 1.0 in the log trace (added to X11DRV_PEN_SelectObject right before the GDI_ROUND call).
well, that's a bug in the debugger... in fact, the debugger passes a float (strictly as a float) to a printf function, which expects a double argument, hence the error this should be a simple fix... let me know if this works better
Index: debugger/info.c =================================================================== RCS file: /usr/share/cvs/cvsroot/wine/wine/debugger/info.c,v retrieving revision 1.17 diff -u -r1.17 info.c --- debugger/info.c 2000/12/29 05:38:00 1.17 +++ debugger/info.c 2001/04/19 21:19:40 @@ -68,8 +68,18 @@ { if (strstr(default_format, "%S") == NULL) { + /* float type has to be promoted as a double */ + /* value.type->un.basic.basic_type == BASIC_FLT */ + if (strstr(default_format, "%f") != NULL) + { + float f; + double d; + memcpy(&f, &res, sizeof(f)); + d = (double)f; + memcpy(&res, &d, sizeof(res)); + } DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, default_format, res ); - } + } else { char* ptr;
"eric pouech" eric.pouech@wanadoo.fr wrote:
well, that's a bug in the debugger... in fact, the debugger passes a float (strictly as a float) to a printf function, which expects a double argument, hence the error this should be a simple fix... let me know if this works better
[patch skipped]
Yes, now wine debugger prints eM11=1.000000 as expected. Thank you.