Status: New
Owner: ----
New issue 1505 by [email protected]: general protection fault due to
misaligned addresses with sse in v8::internal::DateParser::Parse
http://code.google.com/p/v8/issues/detail?id=1505
We built the latest node v0.4 branch on illumos which is using v8 version
3.1.8.16 and gcc 4.5.2. node and v8 were built 32-bit.
We were running code that was parsing a lot of dates and observed a
segmentation fault. When trying to reproduce it, we could occasionally; but
not reliably, do so with the following code:
var d = 'Tue, 21 Jun 2011 18:55:';
new Date(d);
I took a brief look into why we were failing with mdb. First here's the
stack at the time of the dump:
$C
fd8df128
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x473(206e754a,
31313032, 3a383120, 323a3535, 4d472037, fe88e054
)
2c657554 0x20313220()
::dem
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE
== v8::internal::DateParser::Parse<const char>
There are likely more Javascript stack frames, but mdb can't show them.
GCC optimized the function v8::internal::DateParser::Parse<const char> to
use SSE operations. If we look at some of the relevant disassembled output
in mdb:
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x473::dis
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x44e:addl
0x38(%esp),%eax
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x452:cmpl
%ecx,0x34(%esp)
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x456:movl
0x48(%esp),%ebx
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x45a:movl
0x4c(%esp),%edx
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x45e:
je +0xf
<_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x46f>
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x460:movl
$0x0,(%edi,%eax,4)
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x467:addl
$0x1,%eax
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x46a:cmpl
$0x2,%eax
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x46d:
jle -0xf
<_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x460>
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x46f:movl
%edx,0x4(%esp)
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x473:movdqa
%xmm0,0x10(%esp)
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x479:movl
%edi,(%esp)
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x47c:
call +0x21164f
<_ZN2v88internal10DateParser12KeywordTable6LookupEPKji>
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x481:movdqa
0x10(%esp),%xmm0
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x487:
leal 0x850bee0(%eax,%eax,4),%edx
<_ZN2v88internal10DateParser12KeywordTable5arrayE>
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x48e:movsbl
0x3(%edx),%eax
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x492:cmpl
$0x3,%eax
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x495:
je +0xd5
<_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x570>
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x49b:cmpl
$0x1,%eax
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x49e:
je +0xec
<_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x590>
_ZN2v88internal10DateParser5ParseIKcEEbNS0_6VectorIT_EEPNS0_10FixedArrayE+0x4a4:cmpl
$0x2,%eax
We can see that at +0x473 we're doing a movdqa %xmm0,0x10(%esp).
The Intel Assembly manual says that it would raise a GP on the following
conditions:
When the source or destination operand is a memory operand, the operand
must be aligned on a 16-byte boundary or a general-protection exception
(#GP) will be generated. To move integer data to and from unaligned memory
locations, use the VMOVDQU instruction.
If we look at esp we see that it has the following value:
<esp=P
0x80470c4
The instruction wanted 0x10(%esp) or 0x80470d4. My guess as to what's
happening is that gcc is assuming that esp will be aligned and sometimes
when v8 is making the jump from Javascript to C++ execution it ends up with
an esp that is properly aligned and sometimes it isn't.
As a work around one can add -mno-sse to the SConstruct cflags. This
problem doesn't manifest itself if the v8::internal::DateParser::Parse
function does not get optimized to use the SSE registers.
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev