[SERVER-13824] V8-3.12 Segfaults when compiled with GCC 4.9.0 Created: 02/May/14 Updated: 13/Jul/15 Resolved: 21/Jul/14 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | JavaScript |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Mathias Stearn | Assignee: | Adam Midvidy |
| Resolution: | Won't Fix | Votes: | 0 |
| Labels: | community-team | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||
| Backwards Compatibility: | Fully Compatible | ||||||||||||||||||||||||||||||||||||||||
| Operating System: | ALL | ||||||||||||||||||||||||||||||||||||||||
| Sprint: | Server 2.7.3, Server 2.7.4 | ||||||||||||||||||||||||||||||||||||||||
| Participants: | |||||||||||||||||||||||||||||||||||||||||
| Description |
|
| Comments |
| Comment by Githook User [ 31/Jul/14 ] | ||||||||||||||||||||||
|
Author: {u'name': u'Geert Bosch', u'email': u'geert@mongodb.com'}Message: Code will now work correctly with GCC 4.9.x with full optimization. | ||||||||||||||||||||||
| Comment by Geert Bosch [ 26/Jul/14 ] | ||||||||||||||||||||||
|
I tried gcc (GCC) 4.9.2 20140725 (prerelease) and it failed in similar fashion. As GCC developer I wanted to extract a bug report for GCC (if it was indeed a bug in GCC) or otherwise find out what was wrong. A look at the sources in v8utils.h clearly indicates the problem. The assumption is that it is OK to use reinterpret_cast to convert between pointer types. This is undefined in general, but entirely unreasonable if the types have different alignment as is the case here. Indeed the whole purpose of the code is to ignore alignment. True, you might get away with it in some cases, but that doesn't make it correct. Note that the whole notion of "V8_HOST_CAN_READ_UNALIGNED" is flawed. Can read what unaligned? An integer? A floating point double? A 32-byte vector? Answers can differ, and the V8 code is utterly broken in this regard. Unfortunately, even if V8_HOST_CAN_READ_UNALIGNED is false, there is a reinterpret_cast of pointers to uint32_t (even on 64-bit systems!) to try and manually optimize loops for which GCC/glibc would use optimal code if memcmp had simply been called instead of CompareRawStringContents. I have a patch that includes a minimal fix to v8 that essentially omits setting V8_HOST_CAN_READ_UNALIGNED and fixes CompareRawStringContents by removing the code that tries to compare by words. -Geert | ||||||||||||||||||||||
| Comment by Matt Kangas [ 21/Jul/14 ] | ||||||||||||||||||||||
|
GCC 4.9.1 has been released and appears to resolve this issue. We are no longer able to reproduce the segfault. If you must compile with GCC 4.9.0, recommended workarounds include:
Note: our SConstruct does not provide a way to specify alternate compiler options, so you have to hack this line to specify "-O2" rather than "-O3". | ||||||||||||||||||||||
| Comment by Adam Midvidy [ 16/Jul/14 ] | ||||||||||||||||||||||
|
Further investigation shows that this is probably due to an unaligned access occurring in vectorized code, Here is the code generated with -O2 (no crash occurs)
Here is the same code compiled with -O3 (the crash occurs at instruction 0xa66b7c)
Note that the loop has been vectorized to use the xmm registers using the movdqa instruction. From the intel arch documentation: "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." As there is no requirement that the input to CopyChars be aligned, the use of the xmm registers triggers the fault. Furthermore, clang with -O3 does not emit vector instructions for the function in question. | ||||||||||||||||||||||
| Comment by Matt Kangas [ 15/May/14 ] | ||||||||||||||||||||||
|
In
We need do a full test suite run against v2.6 built with gcc-4.9 and see what falls out. | ||||||||||||||||||||||
| Comment by Matt Kangas [ 15/May/14 ] | ||||||||||||||||||||||
|
Demangled stack trace:
|