[erlang-bugs] Mac OS X - trunc for large float causes ERTS_FP_CHECK_INIT at [...]: detected unhandled FPE at [...]

Bob Ippolito <>
Tue May 3 16:18:34 CEST 2011


On Tue, May 3, 2011 at 1:04 AM, Mikael Pettersson <> wrote:
> Bob Ippolito writes:
>  > I only see this error on Mac OS X. I have not been able to reproduce in Linux.
>  >
>  > Here's an example, any number larger than 16#7ffffffffffffe00 will
>  > cause this error.
>  >
>  > Erlang R14B02 (erts-5.8.3) [source] [64-bit] [smp:4:4] [rq:4]
>  > [async-threads:4] [hipe] [kernel-poll:true]
>  >
>  > Eshell V5.8.3  (abort with ^G)
>  > 1> trunc(16#7ffffffffffffdff * 1.0).
>  > 9223372036854774784
>  > 2> trunc(16#7ffffffffffffdff * 1.0).
>  > 9223372036854774784
>  > 3> trunc(16#7ffffffffffffe00 * 1.0).
>  > 9223372036854775808
>  > 4> trunc(16#7ffffffffffffe00 * 1.0).
>  > ERTS_FP_CHECK_INIT at 0x10086210: detected unhandled FPE at
>  > 0x19223372036854775808
>  > 5> trunc(16#7ffffffffffffe00 * 1.0).
>  > ERTS_FP_CHECK_INIT at 0x10086210: detected unhandled FPE at
>  > 0x19223372036854775808
>  > 6> io:format("~s~n", [os:cmd("uname -a")]).
>  > Darwin ba.local 10.7.0 Darwin Kernel Version 10.7.0: Sat Jan 29
>  > 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386 i386
>  >
>  > Here's another example:
>  >
>  > Erlang R14B02 (erts-5.8.3) [source] [64-bit] [smp:4:4] [rq:4]
>  > [async-threads:4] [hipe] [kernel-poll:true]
>  >
>  > Eshell V5.8.3  (abort with ^G)
>  > 1> <<F/float>> = <<67,224,0,0,0,0,0,0>>, trunc(F).
>  > 9223372036854775808
>  > 2> <<F/float>> = <<67,224,0,0,0,0,0,0>>, trunc(F).
>  > ERTS_FP_CHECK_INIT at 0x10083e24: detected unhandled FPE at
>  > 0x19223372036854775808
>  > 3> <<F/float>> = <<67,224,0,0,0,0,0,0>>, trunc(F).
>  > ERTS_FP_CHECK_INIT at 0x10083e24: detected unhandled FPE at
>  > 0x19223372036854775808
>
> It means that the code at 0x19223372036854775808 in the
> Erlang VM needs to use the proper ERTS_FP_CHECK_<foo> macros.
>
> Please attach gdb (or whatever debugger Darwin uses) to a running
> Erlang VM and disassemble the code at 0x19223372036854775808.
> We need to know the name of the enclosing function, and preferably
> also the actual instruction sequence that throws the FPE. If gdb
> can show the exact original source code line then that's even better.
>
> If this is in libc rather than the Erlang VM itself, then we need
> a call trace to identify which code in the VM called out to this
> FP-throwing code.  For that you should probably plant a breakpoint
> at 0x19223372036854775808 and then evaluate one of those Erlang
> expressions above to trigger the FPE.
>

Well, it's actually saying 0x1, the result of the trunc is
9223372036854775808  and the message string is truncated to 64
characters which is not enough to show it all. Perhaps the buffer size
in erts_fp_check_init_error should be adjusted.

My gdb skills are very rusty, let me know if you need anything else
(and how to get it).

(gdb) attach 36833
Attaching to process 36833.
Reading symbols for shared libraries . done
Reading symbols for shared libraries ...... done
0x00007fff87605e52 in select$DARWIN_EXTSN ()
(gdb) b erts_fp_check_init_error
Breakpoint 1 at 0x101209f7: file sys/unix/sys_float.c, line 87.
(gdb) c
Continuing.
[Switching to process 36833]

Breakpoint 1, erts_fp_check_init_error (fpexnp=0x110f2528) at
sys/unix/sys_float.c:87
87	{
(gdb) p (void*)*fpexnp
$1 = (void *) 0x10025433

And in another attach (I don't know how to get gdb out of the state
where it's telling me there's an EXC_ARITHMETIC which I guess is
SIGFPE):

(gdb) break *0x10025433
Breakpoint 1 at 0x10025433: file beam/erl_bif_guard.c, line 301.
(gdb) c
Continuing.
[Switching to process 36833]

Breakpoint 1, double_to_integer [inlined] () at
/Users/bob/src/otp_src_R14B02/erts/emulator/beam/erl_bif_guard.c:301
301		d = x;            /* trunc */
(gdb) list
296	
297	    for (i = ds-1; i >= 0; i--) {
298		ErtsDigit d;
299	
300		x *= dbase;      /* "shift" left */
301		d = x;            /* trunc */
302		xp[i] = d;        /* store digit */
303		x -= d;           /* remove integer part */
304	    }
305	    while ((ds & (BIG_DIGITS_PER_WORD-1)) != 0) {
(gdb) disassemble
Dump of assembler code for function trunc_1:
0x00000000100252c0 <trunc_1+0>:	mov    %rbx,-0x20(%rsp)
0x00000000100252c5 <trunc_1+5>:	mov    %rbp,-0x18(%rsp)
0x00000000100252ca <trunc_1+10>:	mov    %r12,-0x10(%rsp)
0x00000000100252cf <trunc_1+15>:	mov    %r13,-0x8(%rsp)
0x00000000100252d4 <trunc_1+20>:	sub    $0x38,%rsp
0x00000000100252d8 <trunc_1+24>:	mov    %rdi,%rbx
0x00000000100252db <trunc_1+27>:	mov    %esi,%edx
0x00000000100252dd <trunc_1+29>:	and    $0x1,%edx
0x00000000100252e0 <trunc_1+32>:	jne    0x100252e9 <trunc_1+41>
0x00000000100252e2 <trunc_1+34>:	cmpq   $0x58,-0x2(%rsi)
0x00000000100252e7 <trunc_1+39>:	je     0x10025340 <trunc_1+128>
0x00000000100252e9 <trunc_1+41>:	mov    %rsi,%rax
0x00000000100252ec <trunc_1+44>:	and    $0xf,%eax
0x00000000100252ef <trunc_1+47>:	cmp    $0xf,%rax
0x00000000100252f3 <trunc_1+51>:	je     0x10025306 <trunc_1+70>
0x00000000100252f5 <trunc_1+53>:	test   %edx,%edx
0x00000000100252f7 <trunc_1+55>:	je     0x10025330 <trunc_1+112>
0x00000000100252f9 <trunc_1+57>:	movq   $0x350,0x148(%rbx)
0x0000000010025304 <trunc_1+68>:	xor    %esi,%esi
0x0000000010025306 <trunc_1+70>:	mov    %rsi,%rax
0x0000000010025309 <trunc_1+73>:	mov    0x18(%rsp),%rbx
0x000000001002530e <trunc_1+78>:	mov    0x20(%rsp),%rbp
0x0000000010025313 <trunc_1+83>:	mov    0x28(%rsp),%r12
0x0000000010025318 <trunc_1+88>:	mov    0x30(%rsp),%r13
0x000000001002531d <trunc_1+93>:	add    $0x38,%rsp
0x0000000010025321 <trunc_1+97>:	retq
0x0000000010025322 <trunc_1+98>:	nopl   0x0(%rax)
0x0000000010025329 <trunc_1+105>:	nopl   0x0(%rax)
0x0000000010025330 <trunc_1+112>:	mov    -0x2(%rsi),%rax
0x0000000010025334 <trunc_1+116>:	and    $0x3b,%eax
0x0000000010025337 <trunc_1+119>:	cmp    $0x8,%rax
0x000000001002533b <trunc_1+123>:	jne    0x100252f9 <trunc_1+57>
0x000000001002533d <trunc_1+125>:	jmp    0x10025306 <trunc_1+70>
0x000000001002533f <trunc_1+127>:	nop
0x0000000010025340 <trunc_1+128>:	movq   0x6(%rsi),%xmm0
0x0000000010025345 <trunc_1+133>:	xorpd  %xmm1,%xmm1
0x0000000010025349 <trunc_1+137>:	ucomisd %xmm1,%xmm0
0x000000001002534d <trunc_1+141>:	jb     0x100254cb <trunc_1+523>
0x0000000010025353 <trunc_1+147>:	callq  0x1018777a <dyld_stub_floor>
0x0000000010025358 <trunc_1+152>:	movapd %xmm0,%xmm1
0x000000001002535c <trunc_1+156>:	ucomisd 0x172d6c(%rip),%xmm1
# 0x101980d0 <C.73.20233+176>
0x0000000010025364 <trunc_1+164>:	jae    0x10025376 <trunc_1+182>
0x0000000010025366 <trunc_1+166>:	jp     0x10025376 <trunc_1+182>
0x0000000010025368 <trunc_1+168>:	ucomisd 0x172d68(%rip),%xmm1
# 0x101980d8 <C.73.20233+184>
0x0000000010025370 <trunc_1+176>:	ja     0x1002549a <trunc_1+474>
0x0000000010025376 <trunc_1+182>:	xor    %r13d,%r13d
0x0000000010025379 <trunc_1+185>:	xorpd  %xmm0,%xmm0
0x000000001002537d <trunc_1+189>:	ucomisd %xmm0,%xmm1
0x0000000010025381 <trunc_1+193>:	jb     0x100254d9 <trunc_1+537>
0x0000000010025387 <trunc_1+199>:	movsd  0x172d51(%rip),%xmm2        #
0x101980e0 <C.73.20233+192>
0x000000001002538f <trunc_1+207>:	mov    $0x1,%r12d
0x0000000010025395 <trunc_1+213>:	mov    $0xffffffff,%ebp
0x000000001002539a <trunc_1+218>:	ucomisd %xmm2,%xmm1
0x000000001002539e <trunc_1+222>:	jb     0x100253c5 <trunc_1+261>
0x00000000100253a0 <trunc_1+224>:	xor    %ecx,%ecx
0x00000000100253a2 <trunc_1+226>:	movsd  0x172d3e(%rip),%xmm0        #
0x101980e8 <C.73.20233+200>
0x00000000100253aa <trunc_1+234>:	nopw   0x0(%rax,%rax,1)
0x00000000100253b0 <trunc_1+240>:	mulsd  %xmm0,%xmm1
0x00000000100253b4 <trunc_1+244>:	inc    %ecx
0x00000000100253b6 <trunc_1+246>:	ucomisd %xmm2,%xmm1
0x00000000100253ba <trunc_1+250>:	jae    0x100253b0 <trunc_1+240>
0x00000000100253bc <trunc_1+252>:	lea    0x1(%rcx),%eax
0x00000000100253bf <trunc_1+255>:	movslq %eax,%r12
0x00000000100253c2 <trunc_1+258>:	lea    -0x1(%rcx),%ebp
0x00000000100253c5 <trunc_1+261>:	mov    (%rbx),%rcx
0x00000000100253c8 <trunc_1+264>:	mov    0x8(%rbx),%rax
0x00000000100253cc <trunc_1+268>:	sub    %rcx,%rax
0x00000000100253cf <trunc_1+271>:	sar    $0x3,%rax
0x00000000100253d3 <trunc_1+275>:	cmp    %r12,%rax
0x00000000100253d6 <trunc_1+278>:	jb     0x100254ac <trunc_1+492>
0x00000000100253dc <trunc_1+284>:	lea    0x0(,%r12,8),%rdx
0x00000000100253e4 <trunc_1+292>:	lea    (%rcx,%rdx,1),%rax
0x00000000100253e8 <trunc_1+296>:	mov    %rax,(%rbx)
0x00000000100253eb <trunc_1+299>:	mov    %rax,%rdi
0x00000000100253ee <trunc_1+302>:	sub    %rdx,%rdi
0x00000000100253f1 <trunc_1+305>:	lea    0x2(%rdi),%rsi
0x00000000100253f5 <trunc_1+309>:	test   %ebp,%ebp
0x00000000100253f7 <trunc_1+311>:	js     0x10025473 <trunc_1+435>
0x00000000100253f9 <trunc_1+313>:	movslq %ebp,%rax
0x00000000100253fc <trunc_1+316>:	lea    (%rdi,%rax,8),%rcx
0x0000000010025400 <trunc_1+320>:	movsd  0x172ce8(%rip),%xmm3        #
0x101980f0 <C.73.20233+208>
0x0000000010025408 <trunc_1+328>:	movsd  0x172ce8(%rip),%xmm2        #
0x101980f8 <C.73.20233+216>
0x0000000010025410 <trunc_1+336>:	mov    $0x8000000000000000,%r8
0x000000001002541a <trunc_1+346>:	jmp    0x1002542f <trunc_1+367>
0x000000001002541c <trunc_1+348>:	nopl   0x0(%rax)
0x0000000010025420 <trunc_1+352>:	subsd  %xmm0,%xmm1
0x0000000010025424 <trunc_1+356>:	dec    %ebp
0x0000000010025426 <trunc_1+358>:	sub    $0x8,%rcx
0x000000001002542a <trunc_1+362>:	cmp    $0xffffffffffffffff,%ebp
0x000000001002542d <trunc_1+365>:	je     0x10025473 <trunc_1+435>
0x000000001002542f <trunc_1+367>:	mulsd  %xmm3,%xmm1
0x0000000010025433 <trunc_1+371>:	cvttsd2siq %xmm1,%rdx
0x0000000010025438 <trunc_1+376>:	ucomisd %xmm2,%xmm1
0x000000001002543c <trunc_1+380>:	jb     0x1002544e <trunc_1+398>
0x000000001002543e <trunc_1+382>:	movapd %xmm1,%xmm0
0x0000000010025442 <trunc_1+386>:	subsd  %xmm2,%xmm0
0x0000000010025446 <trunc_1+390>:	cvttsd2siq %xmm0,%rdx
0x000000001002544b <trunc_1+395>:	xor    %r8,%rdx
0x000000001002544e <trunc_1+398>:	mov    %rdx,0x8(%rcx)
0x0000000010025452 <trunc_1+402>:	cvtsi2sdq %rdx,%xmm0
0x0000000010025457 <trunc_1+407>:	test   %rdx,%rdx
0x000000001002545a <trunc_1+410>:	jns    0x10025420 <trunc_1+352>
0x000000001002545c <trunc_1+412>:	mov    %rdx,%rax
0x000000001002545f <trunc_1+415>:	shr    %rax
0x0000000010025462 <trunc_1+418>:	and    $0x1,%edx
0x0000000010025465 <trunc_1+421>:	or     %rdx,%rax
0x0000000010025468 <trunc_1+424>:	cvtsi2sdq %rax,%xmm0
0x000000001002546d <trunc_1+429>:	addsd  %xmm0,%xmm0
0x0000000010025471 <trunc_1+433>:	jmp    0x10025420 <trunc_1+352>
0x0000000010025473 <trunc_1+435>:	test   %r13d,%r13d
0x0000000010025476 <trunc_1+438>:	je     0x10025489 <trunc_1+457>
0x0000000010025478 <trunc_1+440>:	shl    $0x6,%r12
0x000000001002547c <trunc_1+444>:	lea    -0x34(%r12),%rax
0x0000000010025481 <trunc_1+449>:	mov    %rax,(%rdi)
0x0000000010025484 <trunc_1+452>:	jmpq   0x10025306 <trunc_1+70>
0x0000000010025489 <trunc_1+457>:	shl    $0x6,%r12
0x000000001002548d <trunc_1+461>:	lea    -0x38(%r12),%rax
0x0000000010025492 <trunc_1+466>:	mov    %rax,(%rdi)
0x0000000010025495 <trunc_1+469>:	jmpq   0x10025306 <trunc_1+70>
0x000000001002549a <trunc_1+474>:	cvttsd2siq %xmm1,%rax
0x000000001002549f <trunc_1+479>:	shl    $0x4,%rax
0x00000000100254a3 <trunc_1+483>:	lea    0xf(%rax),%rsi
0x00000000100254a7 <trunc_1+487>:	jmpq   0x10025306 <trunc_1+70>
0x00000000100254ac <trunc_1+492>:	xor    %edx,%edx
0x00000000100254ae <trunc_1+494>:	mov    %r12,%rsi
0x00000000100254b1 <trunc_1+497>:	mov    %rbx,%rdi
0x00000000100254b4 <trunc_1+500>:	movsd  %xmm1,(%rsp)
0x00000000100254b9 <trunc_1+505>:	callq  0x1004cc40 <erts_heap_alloc>
0x00000000100254be <trunc_1+510>:	mov    %rax,%rdi
0x00000000100254c1 <trunc_1+513>:	movsd  (%rsp),%xmm1
0x00000000100254c6 <trunc_1+518>:	jmpq   0x100253f1 <trunc_1+305>
0x00000000100254cb <trunc_1+523>:	callq  0x101876f0 <dyld_stub_ceil>
0x00000000100254d0 <trunc_1+528>:	movapd %xmm0,%xmm1
0x00000000100254d4 <trunc_1+532>:	jmpq   0x1002535c <trunc_1+156>
0x00000000100254d9 <trunc_1+537>:	xorpd  0x172c2f(%rip),%xmm1        #
0x10198110 <C.73.20233+240>
0x00000000100254e1 <trunc_1+545>:	mov    $0x1,%r13b
0x00000000100254e4 <trunc_1+548>:	jmpq   0x10025387 <trunc_1+199>
End of assembler dump.

-bob


More information about the erlang-bugs mailing list