JDK-8141491 : Unaligned memory access in Bits.c
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 7,8,9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86_64
  • Submitted: 2015-11-04
  • Updated: 2019-03-19
  • Resolved: 2016-02-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8 JDK 9 Other
7u211Fixed 8u192Fixed 9 b108Fixed openjdk7uFixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
This is a follow-on issue to JDK-8140630. When devkit was updated to version 4.9.2 on Linux-x86_64, the JDK test java/nio/Buffer/Basic.java crashed with a SIG_SEGV in Mach5 testing. This is a tier 1 failure.

It was found that compiling src/java.base/share/native/libjava/Bits.c using normal (-O2) optimization instead of high (-O3) resolved the immediate problem. The concern however is that there is an underlying pattern in the optimized compiled code which might manifest itself elsewhere. It would be better to examine the problem in detail in order to find the root cause and hopefully a better solution.
CPU19_01-critical-request for JDK 8 and JDK 7 - Justification : needed to fix very serious regression in latest JDK 8 CPU release (8u191). See JDK-8213088 for details. - Risk Analysis : low risk - Webrev : http://hg.openjdk.java.net/jdk8u/jdk8u-dev/hotspot/rev/79920693f915 http://hg.openjdk.java.net/jdk8u/jdk8u-dev/jdk/rev/8f2ece9973d2 - Testing (done/to-be-done) : jprt testsets passed: default, hotspot manually confirmed jdk/test/java/nio/Buffer/Basic.java now passes - Back ports (done/to-be-done) : 8u-dev pushed / 7u-cpu in-progress - FX Impact : NA - Fix For Release : 8u201/7u211

jtreg testcase in jdk/test/java/nio/Buffer/Basic.java already reproduces the issue so no need to additional testcase.

verified in b139

Please take a look at http://cr.openjdk.java.net/~asmundak/8141491/jdk/webrev.00/ It utilizes the feature provided by some of the compilers (GCC and Clang) to declare item alignment explicitly. I have verified it works on x86_64 Linux.

Please disregard item 1, it's wrong. Sorry about that.

Two comments on the code: 1. In the big endian case the code can use memcpy to copy the whole array from/to buffer. 2. It might be worth leaving the code as is when the buffer turns out to be aligned, that is, have the code in Java_java_nio_Bits_copyFromShortArray be if ((dstAddr % sizeof(jshort)) == 0) { old code } else { your new code }

First attempt at a fix: http://cr.openjdk.java.net/~mikael/webrevs/8141491/webrev.00/webrev/

As a data point, I had a look at what the code looks like on platforms where unaligned memory accesses are less forgiving - specifically (Solaris/)SPARC. I can see that the alignment is in fact checked - the Solaris compiler is more "pessimistic".

Small C repro

Short repro: import java.nio.*; public class HelloBits { public static void main(String[] args) throws Exception { byte[] ba = new byte[1024]; ByteBuffer bb = ByteBuffer.allocateDirect(ba.length); bb.put(ba); bb.position(1); ShortBuffer sb = bb.asShortBuffer(); short[] sa = new short[32]; sb.get(sa, 7, 16); } }

The srcAddr value is 0x7f60e4077931 - or in other words, not quite jshort aligned.

If I am not mistaken, the memory is allocated by Unsafe.allocateMemory() which I think eventually calls os::malloc in hotspot/src/share/vm/runtime/os.cpp ... but my visual code inspection might have missed something.

Note: The "a" in movdqa is short for "aligned", meaning this instruction expects the target address to be aligned.

Here's the SIGSEGV: (gdb) x /i $pc => 0x7f09b7279033 <Java_java_nio_Bits_copyToShortArray+499>: movdqa (%r11,%r9,1),%xmm2 (gdb) p /x $r11 $3 = 0x7f093002a6c1 (gdb) p /x $r9 $4 = 0x0

See also JDK-8140552 for a VM problem with new compilers that is still to be analysed in depth.

Sorry for the misunderstanding, I'll have a quick look at it later tonight.

[~alanb] assigning to you in the hopes that you can find the right person to assign this to.