JDK-8032864 : [macosx] sigsegv (0Xb) Being Generated When Starting JDev With Voiceover Running
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 7,8,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-01-27
  • Updated: 2015-01-21
  • Resolved: 2014-07-22
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
7u76Fixed 8u40Fixed 9 b28Fixed
Related Reports
Relates :  
Relates :  
Description
Technical Environment (Product Version, JDK Version, Patches Applied, etc.):
----------------------------------------------------------------------------
Mac OSX 10.8 mountainLion
jdk 1.7.0_21, 1.7.0_51 (tried the older jdk to see if it was a problem with
the newer jdk build).
JDeveloper 12.1.2.0.0

Problem Description:
--------------------
This problem was reported by a customer.

After installing JDeveloper the customer tried to launch JDeveloper from the
JDeveloper.app app file, and while it starts to launch, eventually it just
hangs.

He then tried running $JDEV_HOME/jdeveloper/jdev/bin/jdev from a terminal
window and was able to determine that a segmentation fault was being
generated (see log file).

The user was running the VoiceOver screenreader on his Mac.

Per a suggestion he tried starting JDeveloper with VoiceOver turned off, and
with sighted assistance.  JDeveloper started fine. He then restarted
VoiceOver and it was able to read JDeveloper's controls fine. 

This is what I see when I start jdeveloper (12.1.2 or 12.1.3) with the Voice
Over enabled:

 Oracle JDeveloper 12c Development Build 12.1.3.0.0
 Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007fff93903250, pid=79792, tid=1799
#
# JRE version: 7.0_21-b12
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.21-b01 mixed mode bsd-amd64
compressed oops)
# Problematic frame:
# C  [libobjc.A.dylib+0x6250]  objc_msgSend+0x10
#
# Core dump written. Default location:
/Users/jdev/Desktop/jdeveloper/jdev/bin/core or core.79792
#
# An error report file with more information is saved as:
# /Users/jdev/Desktop/jdeveloper/jdev/bin/hs_err_pid79792.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
/Users/jdev/Desktop/jdeveloper/jdev/bin/../../ide/bin/launcher.sh: line 1193:
79792 Abort trap: 6           (core dumped) ${JAVA} "${APP_VM_OPTS[@]}"
${APP_ENV_VARS} -classpath ${APP_CLASSPATH} ${APP_MAIN_CLASS}
"${APP_APP_OPTS[@]}"




Comments
re-aasigned back from sustaining as an issue in jdk 9
16-06-2014

We were thinking about this and the only real solution would be to avoid processing dispose selectors while we are in the inner loop. I will have to do some prototyping and see how this affects us.
27-03-2014

Hi Petr, wondering if you got chance to dig into this, and if there is some feasible solution for this.
18-03-2014

I've implemented the approach I've proposed previously, but it does not help��� Looks like in this case something different is happening, so I'll continue the research..
14-03-2014

Hmm.. This is quite deep Cocoa internals, so we could only guess... From my understanding it's possible, but we've never seen this, so it's either extremely unlikely or indeed impossible. I'll try to implement the approach I've described above and see what's happening.
13-03-2014

It is interesting. One general question: is it possible to call SEL1 and after that immediately adds SEL_DISPOSE(somehow) -> new selectors from SEL1 will be added after or before SEL_DISPOSE? Can we really fix that in general? Possibly it should be fixed on cocoa side, it should retain the necessary nswindow before it posts a new selectors?
13-03-2014

Now I know what's happening. When accessibility code needs to get some info from Java it starts a nested runLoop on the Appkit thread while waiting for and answer from EDT. This nested loop is needed to avoid deadlocks in case a synchronous task on EDT would need to do some synchronous task on Appkit. This nested loop is run using the javaRunLoop mode, because all our selectors are posted to the Appkit using this mode via JNFRunLoop. So when we are in the nested loop we first process selectors posted using JavaRLMode and only then others. So: 1. On EDT we call setVisible and immediately dispose other window. This results in several selectors posted to AppKit by us and dispose is the final one (These all have JavaRLMode) So, the native Queue looks like this: SEL1(JavaRLMode), SEL_DISPOSE(javaRLMode) 2. Appkit starts to perform the selectors we've posted and also posts selectors internally. The internal selectors have DafaultRLMode. By this time the Appkit queue looks like this: SEL_DISPOSE(javaRLMode), SEL_INTERNAL1(DefaultRLMode), SEL_INTERNAL2(DefaultRLMode). In our case some SEL_INTERNAL1 is triggering a11y and starting the nested loop and SEL_INTERNAL2 sends the message to the previous first responder which we want to dispose in SEL_DISPOSE. 3. Normally, without a11y the selectors would be processed in the following order: SEL_INTERNAL1, SEL_INTERNAL2, SEL_DISPOSE. This is because the default runloop mode is current. 4. However with a11y the following happen: the main RL processes SEL_INTERNAL1. It triggers a11y which starts a nested run loop. The nested runLoop starts in the JavaRLMode, so it processes the SEL_DISPOSE first and only then SEL_INTERNAL2. Crash! Although it's quite clear what's happening, it is absolutely not obvious what to do. The problem is quite general, because this is an example how nested loop could reorder the selectors and break Cocoa internals. We've seen some other similar bugs. The only idea I have is to get rid of the JNFRunLoop and switch to the default runloop mode the same way we do it in JavaFX. This, however, would be a tremendous change which is only OK for 9 and could be backported after lot's of testing. I'll try to think of some simpler workaround.
13-03-2014

Since mac a11y is fairly broken once you determine the root cause it will be good to review the rest of the code for the same issue.
13-03-2014

Thanks Petr, I tracked the AWTWindow_Normal retain/release/dealloc, the object was deallocated before receiving message. Question now is why the window is destroyed earlier and how to retain it until the accessibility message is fully done. I saw the AWTWindow and AWTView both have accessibilityIsIgnored set to YES, AWTView has accessibility related functionalities, which could be another area to audit.
12-03-2014

The standalone test case was attached. The issue is also reproducible with 8 and 9. We are not sure about the root cause of the problem yet, need more investigation.
12-03-2014

Problem is message is still sent to a AWTWindow which is already deallocated. Auditted the code, The initial and release of AWTWindow_Normal looks alright, nsWindow is a retain property, setter is going to increase the retainCount by 1, so there is a release followed by alloc to decrease the retaincount by 1. Crash will be gone if we remain the retainCount of NSWindow to 2 after init, but I'm afraid that will lead to leak. My suspicious is this could caused by different threads (Native & Java) accessing same AWTWindow object without safe lock, but not sure. Would like to talk to someone to Dev for further diagnosis.
12-03-2014

Turned on NSZombieEnabled and from instrument, added, looks like a Message was sent to a window already got deallocated. See "0x7f8e43c41260" below: 3/11/14 3:30:36.783 PM java[99595]: Vivi Init AWTWindow_Normal - 0x7f8e43ce09b0 for 0x7f8e43ce07d0 3/11/14 3:30:36.851 PM java[99595]: Vivi Init AWTWindow_Normal - 0x7f8e43c41260 for 0x7f8e43c37290 3/11/14 3:30:41.162 PM java[99595]: Vivi Init AWTWindow_Normal - 0x7f8e47ebb880 for 0x7f8e47ebb6d0 3/11/14 3:30:51.094 PM java[99595]: Vivi Init AWTWindow_Normal - 0x7f8e4ca41790 for 0x7f8e4b67f370 3/11/14 3:30:51.433 PM java[99595]: Vivi Init AWTWindow_Normal - 0x7f8e4c97a6a0 for 0x7f8e4c97a520 3/11/14 3:30:51.481 PM java[99595]: Vivi dealloc AWTWindow_Normal - 0x7f8e43c41260 for 0x7f8e43c37290 3/11/14 3:30:51.491 PM java[99595]: Vivi dealloc AWTWindow_Normal - 0x7f8e47ebb880 for 0x7f8e47ebb6d0 3/11/14 3:30:51.494 PM java[99595]: Vivi dealloc AWTWindow_Normal - 0x7f8e43ce09b0 for 0x7f8e43ce07d0 3/11/14 3:30:51.564 PM java[99595]: *** -[AWTWindow_Normal _acceptsSecondaryKey]: message sent to deallocated instance 0x7f8e43c41260
11-03-2014

On 13.02.2014 2:32, Scott Kovatch wrote: > Something is being added to a window, and a callback is making it the first responder. > > C [JavaNativeFoundation+0x3b31] JNFCallStaticObjectMethod+0xae > C [liblwawt.dylib+0x35af2] -[JavaComponentAccessibility > accessibilityFocusedUIElement]+0x67 > C [liblwawt.dylib+0x19761] -[AWTView accessibilityFocusedUIElement]+0x9c > C [AppKit+0x1144d9] NSAccessibilityHandleFocusChangedForce+0x69 > C [AppKit+0x1f192c] -[NSWindow makeFirstResponder:]+0x3d2 > C [liblwawt.dylib+0x18c16] __-[AWTView > viewDidMoveToWindow]_block_invoke_1+0x7d > > But since VoiceOver is on, it's triggering a change in the accessibility state, so we get a callback for the focused control. The crash happens when -[JavaComponentAccessibility accessibilityFocusedUIElement] calls into Java, which then calls back out to native code to do something on the main thread, but my guess is something wasn't retained properly, so you're sending a message to a freed object. > > I'd look in either of these methods: > > C [liblwawt.dylib+0x35af2] -[JavaComponentAccessibility accessibilityFocusedUIElement]+0x67 > C [liblwawt.dylib+0x19761] -[AWTView accessibilityFocusedUIElement]+0x9c > > which implies it's an AWT issue. > > -- Scott
15-02-2014

On 13.02.2014 4:40, Mike Swingler wrote: > That stack trace seems to indicate that an NSObject was over-released, and then was called in an async callback on the main thread. > > I'd suggest setting the NSZombieEnabled environment variable to 1, and reproducing. That should tell you what kind of object it was that was overreleased. > > ~Mike
15-02-2014

Hi Vivi (and Stephen), Java accessibility is pretty broken on Mac. I'd be surprised if it was working well enough for anyone to do real work. So from a bigger picture perspective, at least to get the priority of this correct, it would be good to know why the customer is using a Mac for access to Java apps and if there is any reason why they can't use a Win machine other than personal preference. If Java accessibility on the Mac is a critical and urgent issue then development will have to factor this into our plans for this year. Other than that I don't have any ideas off the top of my head regarding debugging as it has been quite a long time since I worked on the Mac code but I will look at it again tomorrow. Pete
11-02-2014

Crash stack trace from BugDB: C [libobjc.A.dylib+0x6250] objc_msgSend+0x10 C [Foundation+0x935ca] __NSThreadPerformPerform+0xe1 C [CoreFoundation+0x12b31] __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__+0x11 C [CoreFoundation+0x12455] __CFRunLoopDoSources0+0xf5 C [CoreFoundation+0x357f5] __CFRunLoopRun+0x315 C [CoreFoundation+0x350e2] CFRunLoopRunSpecific+0x122 C [Foundation+0x9b7ee] -[NSRunLoop(NSRunLoop) runMode:beforeDate:]+0x10c C [liblwawt.dylib+0x39e88] Java_sun_lwawt_macosx_LWCToolkit_doAWTRunLoop+0xee j sun.lwawt.macosx.LWCToolkit.doAWTRunLoop(JZZ)V+0 j sun.lwawt.macosx.LWCToolkit.invokeAndWait(Ljava/lang/Runnable;Ljava/awt/Compon ent;Z)V+57 j sun.lwawt.macosx.LWCToolkit.invokeAndWait(Ljava/lang/Runnable;Ljava/awt/Compon ent;)V+3 j sun.lwawt.macosx.LWCToolkit.invokeAndWait(Ljava/util/concurrent/Callable;Ljava /awt/Component;)Ljava/lang/Object;+11 j sun.lwawt.macosx.CAccessibility.invokeAndWait(Ljava/util/concurrent/Callable;L java/awt/Component;)Ljava/lang/Object;+2 j sun.lwawt.macosx.CAccessibility.getFocusOwner(Ljava/awt/Component;)Ljavax/acce ssibility/Accessible;+8 v ~StubRoutines::call_stub V [libjvm.dylib+0x288abb] V [libjvm.dylib+0x288888] V [libjvm.dylib+0x2a4096] V [libjvm.dylib+0x29b519] C [JavaNativeFoundation+0x3b31] JNFCallStaticObjectMethod+0xae C [liblwawt.dylib+0x35af2] -[JavaComponentAccessibility accessibilityFocusedUIElement]+0x67 C [liblwawt.dylib+0x19761] -[AWTView accessibilityFocusedUIElement]+0x9c C [AppKit+0x1144d9] NSAccessibilityHandleFocusChangedForce+0x69 C [AppKit+0x1f192c] -[NSWindow makeFirstResponder:]+0x3d2 C [liblwawt.dylib+0x18c16] __-[AWTView viewDidMoveToWindow]_block_invoke_1+0x7d .... .... . The crash happens in objc_msgSend() in libobjc library. The last call from JRE was '[liblwawt.dylib+0x39e88] Java_sun_lwawt_macosx_LWCToolkit_doAWTRunLoop+0xee'
11-02-2014