JDK-4908942 : JAVA program hangs with XInitThreads call with JDK1.4, but works with JDK1.3.1
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.4.2
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: linux,solaris_8
  • CPU: x86,sparc
  • Submitted: 2003-08-19
  • Updated: 2014-02-14
  • Resolved: 2004-03-13
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.
Other
1.4.2_05 05Fixed
Related Reports
Relates :  
Relates :  
Description
Name: pa48320			Date: 08/19/2003


==================================================================================
                            List of Files
==================================================================================


- readme.txt
- jnitest.c
- Test.java
- TestDialog.java
- ENV
- build_NOUIHANG
- build_UIHANG
- jnitest.sh


==================================================================================
                      FILE : README
==================================================================================


Environment settings to build and run the test case:
---------------------------------------------------

- Edit and set the JAVA_HOME, MOTIF_HOME in the file ENV
- Set the variable  JAVA_HOME to where JDK 1.4.2 is installed
- Set the varibale XWIN_HOME to where X11 library is present
  for ex: /usr/X11R6
- Set the DISPLAY to where X-server is running on Linux platform

How to build the testcase:
-------------------------

- Source the environment file ENV
- run shell script build_UIHANG.sh to create a test case
  to reproduce the problem
- run shell script build_NOUIHANG.sh, to create a test case
  which does not reproduce problem

How to reprouce the problem:
---------------------------

- Build the testcase using build_UIHANG.sh script
- The run the testcase using following steps

How to run the testcase:
-------------------------

- Source the environment file ENV
- run shell script jnitest.sh to run the testcase
- Click Ok , if JAVA  UI comes up fine then
  problem does not reproduce, if JAVA UI comes
  up blank, and program hangs then problem reproduces
- Click Exit to finish

=================================================================================
                   FILE : ENV
=================================================================================

A) File ENV:
-----------

JAVA_HOME=/usr/local/java/j2sdk1.4.1_02; export JAVA_HOME
XWIN_HOME=/usr/X11R6; export XWIN_HOME
RMF="/bin/rm -f"; export RMF

LD_LIBRARY_PATH=${JAVA_HOME}/jre/lib/i386/server:${JAVA_HOME}/jre/lib/i386/native_threads:${JAVA_HOME}/jre/lib/i386; export LD_LIBRARY_PATH

CLASSPATH=.:$CLASSPATH; export CLASSPATH


=================================================================================
                  FILE : build_UIHANG.sh
=================================================================================

#! /bin/sh

if [ "x$JAVA_HOME" = 'x' ]
then
echo "JAVA_HOME is not set, please source the file ENV....."
exit 1
fi

if [ -r $JAVA_HOME ]; then
  echo ""
else
  echo "Error: Cannot read JAVA_HOME $JAVA_HOME exiting..."
  exit 1
fi

if [ "x$XWIN_HOME" = 'x' ]
then
echo "XWIN_HOME is not set, please source the file ENV....."
exit 1
fi

if [ -r $XWIN_HOME ]; then
  echo ""
else
  echo "Error: Cannot read XWIN_HOME $MOTIF_HOME exiting..."
  exit 1
fi


/bin/rm -f jnitest.o
/bin/rm -f jnitest
/bin/rm -f Test.class
/bin/rm -f TestDialog.class

/usr/bin/gcc -c jnitest.c -DUIHANG -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux -I${XWIN_HOME}/include -I${XWIN_HOME}/include/X11

/usr/bin/gcc -o jnitest jnitest.o -L${XWIN_HOME}/lib  -lX11 -L${JAVA_HOME}/jre/lib/i386 -L${JAVA_HOME}/jre/lib/i386/server -L${JAVA_HOME}/jre/lib/i386/native_threads -ljvm -lhpi

${JAVA_HOME}/bin/javac Test.java

${JAVA_HOME}/bin/javac TestDialog.java


=================================================================================
                  FILE : build_NOUIHANG.sh
=================================================================================

#! /bin/sh

if [ "x$JAVA_HOME" = 'x' ]
then
echo "JAVA_HOME is not set, please source the file ENV....."
exit 1
fi

if [ -r $JAVA_HOME ]; then
  echo ""
else
  echo "Error: Cannot read JAVA_HOME $JAVA_HOME exiting..."
  exit 1
fi

if [ "x$XWIN_HOME" = 'x' ]
then
echo "XWIN_HOME is not set, please source the file ENV....."
exit 1
fi

if [ -r $XWIN_HOME ]; then
  echo ""
else
  echo "Error: Cannot read XWIN_HOME $MOTIF_HOME exiting..."
  exit 1
fi


/bin/rm -f jnitest.o
/bin/rm -f jnitest
/bin/rm -f Test.class
/bin/rm -f TestDialog.class

/usr/bin/gcc -c jnitest.c -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux -I${XWIN_HOME}/include -I${XWIN_HOME}/include/X11

/usr/bin/gcc -o jnitest jnitest.o -L${XWIN_HOME}/lib  -lX11 -L${JAVA_HOME}/jre/lib/i386 -L${JAVA_HOME}/jre/lib/i386/server -L${JAVA_HOME}/jre/lib/i386/native_threads -ljvm -lhpi

${JAVA_HOME}/bin/javac Test.java

${JAVA_HOME}/bin/javac TestDialog.java


=================================================================================
                  FILE : jnitest.sh
=================================================================================

#! /bin/sh

. ./ENV

./jnitest


===================================================================================
                  FILE: jnitest.c (Test case Source code)
===================================================================================

#include <jni.h>

int main()
 {
	 JavaVMOption options[2];
	 JNIEnv *env;
	 JavaVM *jvm;
	 JavaVMInitArgs vm_args;
	 long status;
	 jclass cls;
	 jmethodID mid;
	 jint square;
	 jboolean not;

	 options[0].optionString = "-Djava.class.path=.";
   options[1].optionString = "-Xmx256M";
	 memset(&vm_args, 0, sizeof(vm_args));
	 vm_args.version = JNI_VERSION_1_2;

	 vm_args.nOptions = 2;
	 vm_args.options = options;

#ifdef UIHANG
	XInitThreads();
#endif /* UIHANG */

	 status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
   printf("Starting...");

	 if (status != JNI_ERR)
	 {
     printf("Starting...1");
		 cls = (*env)->FindClass(env, "Test");
		 if(cls !=0)
		 {
			 //mid = (*env)->GetStaticMethodID(env, cls, "main", "(I)I");
       mid = (*env)->GetStaticMethodID(env, cls, "main", "(I)V");
       printf("MID IS %d",mid);
			 if(mid !=0)
			 {
				 square = (*env)->CallStaticIntMethod(env, cls, mid, 5);
				 printf("Result of intMethod: %d\n", square);
			 }

			 mid = (*env)->GetStaticMethodID(env, cls, "main", "(Z)Z");
			 if(mid !=0)
			 {
				not = (*env)->CallStaticBooleanMethod(env, cls, mid, 1);
				printf("Result of booleanMethod: %d\n", not);
			 }
	 	 }

	 	(*jvm)->DestroyJavaVM(jvm);
	 	return 0;
	 }
	 else
     printf("Java Error");
	 return -1;
 }

===================================================================================
                  FILE: Test.java (Test case Source code)
===================================================================================

import  javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Test extends JFrame implements ActionListener{


public Test(){
	setSize(300,300);
	JLabel l = new JLabel();
	JButton b = new JButton("Ok");
	JButton c = new JButton("Exit");
	b.addActionListener(this);
	getContentPane().setLayout(new GridLayout(3,1));
	getContentPane().add(l);
	l.setText("Click OK to enter data, Exit to finish");
	getContentPane().add(b);
	c.addActionListener(this);
	getContentPane().add(c);
	setVisible(true);

}

	public void actionPerformed(ActionEvent e){
                if (e.getActionCommand().equals("Ok"))
                {
		     TestDialog t = new TestDialog(this);
                }
                else if(e.getActionCommand().equals("Exit"))
                {
		     System.exit(0);
                }

	}
	public static void main(int i){
		new Test();

	}
}



===================================================================================
                  FILE: TestDialog.java (Test case Source code)
===================================================================================


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class TestDialog extends JDialog implements KeyListener{

	public void keyPressed(KeyEvent k){
	System.out.println("Key Pressed");
	}
	public void keyReleased(KeyEvent k){
	System.out.println("Key Released");
	}
	public void keyTyped(KeyEvent k){
	System.out.println("Key Typed");
	}
 	public TestDialog(JFrame par){
		super(par,"TestDialog",true);
		addKeyListener(this);
		JPanel p = new JPanel();
		p.setLayout(new GridLayout(4,1));
		JTextField t1 = new JTextField();
		JTextField t2 = new JTextField();
		JTextField t3 = new JTextField();
		JButton b = new JButton("Ok");
		p.add(t1);
		p.add(t2);
		p.add(t3);
		p.add(b);
		getContentPane().add(p);
		setSize(300,300);
		setLocation(200,200);
		setVisible(true);

	}
}
(Incident Review ID: 199089) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.4.2_05 generic tiger-beta2 FIXED IN: 1.4.2_05 tiger-beta2 INTEGRATED IN: 1.4.2_05 tiger-b43 tiger-beta2 VERIFIED IN: 1.4.2_05
24-08-2004

EVALUATION Client code should not call XInitThreads(). Documentation for XInitThreads() indicates that if it is used, it must be the first Xlib call. By calling XInitThreads() a situation is created where threading related parts of the AWT Display structure were not initialized, but xlib locking is turned on. ###@###.### 2003-08-19 Here is a thread dump I took on RHAS2.1 with 1.4.2: It looks like it is blocking on our first call to Xlib. bash-2.05$ sh jnitest.sh Full thread dump Java HotSpot(TM) Server VM (1.4.2-b28 mixed mode): "Signal Dispatcher" daemon prio=1 tid=0x080b5658 nid=0x6432 waiting on condition [0..0] "Finalizer" daemon prio=1 tid=0x080b12c8 nid=0x6430 in Object.wait() [58cc6000..58cc68c8] at java.lang.Object.wait(Native Method) - waiting on <0x466a7c08> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:111) - locked <0x466a7c08> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159) "Reference Handler" daemon prio=1 tid=0x080b0e58 nid=0x642f in Object.wait() [58c45000..58c458c8] at java.lang.Object.wait(Native Method) - waiting on <0x466a7c70> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:429) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:115) - locked <0x466a7c70> (a java.lang.ref.Reference$Lock) "main" prio=1 tid=0x0804c960 nid=0x642c runnable [bffeb000..bffec2c8] at sun.awt.motif.MToolkit.init(Native Method) at sun.awt.motif.MToolkit.<init>(MToolkit.java:107) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:274) at java.lang.Class.newInstance0(Class.java:308) at java.lang.Class.newInstance(Class.java:261) at java.awt.Toolkit$2.run(Toolkit.java:760) at java.security.AccessController.doPrivileged(Native Method) at java.awt.Toolkit.getDefaultToolkit(Toolkit.java:739) - locked <0x54b5a5b0> (a java.lang.Class) at java.awt.Window.getToolkit(Window.java:688) at java.awt.Window.init(Window.java:246) at java.awt.Window.<init>(Window.java:275) at java.awt.Frame.<init>(Frame.java:401) at java.awt.Frame.<init>(Frame.java:366) at javax.swing.JFrame.<init>(JFrame.java:154) at Test.<init>(Test.java:8) at Test.main(Test.java:36) "VM Thread" prio=1 tid=0x080ae410 nid=0x642e runnable "VM Periodic Task Thread" prio=1 tid=0x080b9900 nid=0x6436 waiting on condition "Suspend Checker Thread" prio=1 tid=0x080b4be8 nid=0x6431 runnable I also tested with Tiger build 17 and XAWT. It looks even more clear that our first call to Xlib blocks. "main" prio=1 tid=0x0804d658 nid=0x6543 runnable [bffec000..bffed608] at sun.awt.X11.XlibWrapper.XKeysymToKeycode(Native Method) at sun.awt.X11.XToolkit.keysymToPrimaryKeycode(XToolkit.java:1118) - locked <0x54dd08b8> (a java.lang.Class) at sun.awt.X11.XToolkit.setupModifierMap(XToolkit.java:1134) at sun.awt.X11.XToolkit.<clinit>(XToolkit.java:102) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:141) at java.awt.Toolkit$2.run(Toolkit.java:786) at java.security.AccessController.doPrivileged(Native Method) at java.awt.Toolkit.getDefaultToolkit(Toolkit.java:769) - locked <0x54da4960> (a java.lang.Class) at java.awt.Window.getToolkit(Window.java:737) at java.awt.Window.init(Window.java:257) at java.awt.Window.<init>(Window.java:290) at java.awt.Frame.<init>(Frame.java:402) at java.awt.Frame.<init>(Frame.java:367) at javax.swing.JFrame.<init>(JFrame.java:154) at Test.<init>(Test.java:8) at Test.main(Test.java:36) The test does execute with 1.3.1, but not 1.4.0. None of the printfs in jnitest.c fired, indicating that it blocked while calling JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); ###@###.### 2003-08-29 We can only reproduce this when running on Linux (e.g. RHAS 2.1) and remote display set to Solaris (e.g. S9U2). We cannot reproduce it when running locally on Solaris, remote displaying between linux machines, or remote displaying from Solaris to Linux. I've reopened the bug. I should note that XInitThreads is called before the VM is created, so it is, in fact, the first Xlib call. ###@###.### 2003-09-02 I compiled the Xlib with Thread debugging enabled and looked at the output from Xlib for the sample program provided, Below is the debug output when the hang occurs: PeekEvent.c line 46: thread d unlocking display Pending.c line 38: thread d got display lock Pending.c line 43: thread d unlocking display NextEvent.c line 43: thread d got display lock NextEvent.c line 50: thread d unlocking display Context.c line 262: thread d got display lock Context.c line 264: thread d unlocking display ChkIfEv.c line 54: thread d got display lock Xlib ERROR: Context.c line 262 thread d: locking display already locked at ChkIfEv.c line 54 These are both Xlib functions, so this might be an Xlib bug ###@###.### 2003-09-12 I talked to Alan Coopersmith from the X group and they suggested to file a bug. ###@###.### 2003-09-12 I have managed to prove that this is an Xlib bug : Look at the stack trace below : =>[1] __lwp_park(0x0, 0x0, 0x0, 0x0, 0x1, 0x22150), at 0xfea55dd4 [2] mutex_lock_queue(0xfea68b44, 0x0, 0x11ae20, 0xfea68000, 0xff346310, 0xe49feab0), at 0xfea51bb4 [3] slow_lock(0x11ae20, 0xfe8f1800, 0x106, 0xd, 0xff393430, 0x36), at 0xfea525b4 [4] _XLockDisplayWarn(0x13ab48, 0xff393184, 0x106, 0x0, 0x586d53, 0x585300), at 0xff365314 [5] _XLockDisplay(0x13ab48, 0xff393184, 0x106, 0xfbcf4000, 0xffdb5dc8, 0x0), at 0xff346310 [6] XFindContext(0x13ab48, 0x2a8998, 0xfffffffd, 0xe447f02c, 0xfe231014, 0xe447f04c), at 0xff32c5b8 [7] _XmGetWidgetExtData(0x2a8998, 0x3, 0x214c, 0xe4991660, 0xe470cccc, 0x2), at 0xe474ac4c [8] _XmGetFocusData(0x2a8998, 0x150588, 0x467cc8, 0x290070, 0x0, 0x0), at 0xe4759728 [9] XmGetFocusWidget(0x2a8998, 0x6f, 0x56458, 0x7f, 0x291, 0x0), at 0xe47b5a8c [10] 0xe49a85a8(0xe4ce3a50, 0x19f5cc, 0xe447f440, 0x23ff70, 0xff346310, 0xe49feab0), at 0xe49a85a7 [11] XCheckIfEvent(0x19f5cc, 0xe447f3e0, 0xe49a845c, 0xe447f440, 0x13ab48, 0xe447f45d), at 0xff339aa0 [12] 0xe499f744(0x2f0250, 0x118f64, 0xe447f790, 0x2effa0, 0x0, 0x23ff70), at 0xe499f743 [13] XtDispatchEventToWidget(0xe447f4cc, 0xe447f790, 0x63f80, 0xa, 0xe49feab0, 0xe4a029a0), at 0xfbcbe550 [14] _XtDefaultDispatcher(0xe447f790, 0x0, 0xa, 0x290834, 0xfbcbd850, 0xe4a029a0), at 0xfbcbdf0c [15] XtDispatchEvent(0xe447f790, 0x44f6b0, 0x2f0250, 0xe4a02a08, 0xe499702c, 0x44f6b0), at 0xfbcbda34 [16] 0xe49974a8(0x0, 0x67a28, 0x8, 0x358, 0xe49feab0, 0x23ff70), at 0xe49974a7 [17] 0xe4996e24(0x23ff70, 0x13ab48, 0x0, 0x5, 0xe49feab0, 0xe4a03820), at 0xe4996e23 [18] Java_sun_awt_motif_MToolkit_run(0x23ff70, 0xfedc3914, 0x67e84, 0xfee377c8 What is happening is that Xt calls XCheckIfEvent with a predicate function that calls XFindContext. Since the XCheckIfEvent already called LockDisplay and XFindContext calls LockDisplay it gets blocked. This is because the default mutex in pthreads is not recursive. They are using the default pthread_mutex initializer. So to solve the problem they either need to use recursive mutexes or change the code of XCheckIfEvent as below. ------- ChkIfEv.c ------- *** /tmp/sccs.hVaaRi Fri Sep 12 19:04:21 2003 --- ChkIfEv.c Fri Sep 12 19:03:39 2003 *************** *** 57,69 **** --- 57,72 ---- for (qelt = prev ? prev->next : dpy->head; qelt; prev = qelt, qelt = qelt->next) { + UnlockDisplay(dpy); if(qelt->qserial_num > qe_serial && (*predicate)(dpy, &qelt->event, arg)) { + LockDisplay(dpy); *event = qelt->event; _XDeq(dpy, prev, qelt); UnlockDisplay(dpy); return True; } + LockDisplay(dpy); } if (prev) qe_serial = prev->qserial_num; With this change in place the testcase work fine without a hang. ###@###.### 2003-09-12 I hope this is clear from the customer call record, but Oracle says they can easily reproduce the problem on Solaris 8 on a local display. ###@###.### 2003-09-18 Adding the UnlockDisplay calls shown is not safe - if another thread modified the event linked list while the display is unlocked, the client could crash. Transferring to the Motif group to determine if Motif can find a way to not make calls that require getting the lock from the code being called from XCheckIfEvent. ###@###.### 2003-11-17 ###@###.### 2003-12-01 Below are my investigation result. 1. Your new trace stack is not the same one as the original one when the bug reported. Moreover, the new deadlock shouldn't exist due to bug fix of 4041914 2. FindContext where display tried to be locked is invoked by callback, it should be impossible to avoid invoking it during the excuting of XCheckIfEvent. 3. For item 2, the original deadlock is hard to fix. The solution I can think out is to add thread mutex and unlock display before XFindContext like below. However, for this solution, libXm.so.4 need to be told if current display is locked before XFindeContext, and it's better that libX11 provide such an API, for example, Boolen XIfDispLocked(). From my investigation, I found there are some other similar bugs before(4041949, for instance). So, adding the API is worth and will not break the fundamental libX11 just as Alan hopes. *** 659,666 **** XmAssocData assocData = NULL; XmAssocData *assocDataPtr; XContext widgetExtContext = ExtTypeToContext(extType); ! ! if ((XFindContext(XtDisplay(widget), (Window) widget, widgetExtContext, --- 659,668 ---- XmAssocData assocData = NULL; XmAssocData *assocDataPtr; XContext widgetExtContext = ExtTypeToContext(extType); ! ! _XmWidgetToAppContext(widget); ! _XmAppLock(app); ! XUnlockDisplay(XtDisplay(widget)); if ((XFindContext(XtDisplay(widget), (Window) widget, widgetExtContext, *************** *** 669,678 **** --- 671,684 ---- #ifdef DEBUG XmeWarning(NULL, "no extension data on stack"); #endif /* DEBUG */ + XLockDisplay(XtDisplay(widget)); + _XmAppUnlock(app); return NULL; } else { + XLockDisplay(XtDisplay(widget)); + _XmAppUnlock(app); assocDataPtr = &assocData; while ((*assocDataPtr)->next) assocDataPtr = &((*assocDataPtr)->next); ###@###.### 2004-01-08 The Xlib standard specification for XCheckIfEvents states: 11.4.2. Selecting Events Using a Predicate Procedure Each of the functions discussed in this section requires you to pass a predicate procedure that determines if an event matches what you want. Your predicate procedure must decide if the event is useful without calling any Xlib functions. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If the predicate directly or indirectly causes the state of the event queue to change, the result is not defined. If Xlib has been initialized for threads, the predicate is called with the display locked and the result of a call by the predicate to any Xlib function that locks the display is not defined unless the caller has first called XLockDisplay. ###@###.### 2004-01-09 If that's the case, then we need to find out who is calling XCheckIfEvents. I used debug versions of libXm, libXt, and libX11, and I still get some functions that are unnamed. These probably are coming from Java: =>[6] _XLockDisplay(dpy = 0x136f10), line 491 in "locking.c" [7] XFindContext(display = 0x136f10, rid = 3316024U, context = -3, data = 0xe6980e70), line 262 in "Context.c" [8] _XmGetWidgetExtData(widget = 0x329938, extType = 3U), line 667 in "BaseClass.c" [9] _XmGetFocusData(wid = 0x329938), line 1079 in "Traversal.c" [10] XmGetFocusWidget(wid = 0x329938), line 1571 in "Traversal.c" [11] 0xfb9b6250(0x136f10, 0x61584, 0xe69812d8, 0xff1c597c, 0x82, 0x0), at 0xfb9b624f [12] XCheckIfEvent(dpy = 0x136f10, event = 0xe6981278, predicate = 0xfb9b6108, arg = 0xe69812d8 "\xe6\x98^V\x90^E\xc0"), line 61 in "ChkIfEv.c" [13] 0xfb9ad2d0(0x0, 0x93ee0, 0xe6981690, 0xe6981389, 0x22768, 0x0), at 0xfb9ad2cf [14] XtDispatchEventToWidget(widget = 0x329938, event = 0xe6981690), line 978 in "Event.c" [15] _XtDefaultDispatcher(event = 0xe6981690), line 1437 in "Event.c" [16] XtDispatchEvent(event = 0xe6981690), line 1517 in "Event.c" [17] 0xfb9a4e6c(0x1, 0x1, 0x33, 0xfb9e1224, 0x41a4, 0x0), at 0xfb9a4e6b [18] 0xfb9a4840(0x61f74, 0xfb9f80c4, 0x0, 0x0, 0x0, 0x0), at 0xfb9a483f [19] Java_sun_awt_motif_MToolkit_run(0x61f74, 0xe698188c, 0x0, 0x0, 0x0, 0x0), at 0xfb9a46b8 From the source of XtDispatchEventToWidget(): line 978: for (i = 0; i < numprocs && cont_to_disp; i++) (*(proc[i]))(widget, closure[i], event, &cont_to_disp); It appears to calling an event handler. libXm and libXt add event handlers and those show up in dbx. However, some handlers are not shown in dbx, so those may be coming from java: (dbx) print proc[i] proc[i] = 0xfb9ad180 (dbx) print proc[i-1] proc[i-1] = 0xe6698dd0 = &_XmTrackShellFocus() (dbx) print proc[i+1] proc[i+1] = 0xfb83b4c4 = &_XtHandleFocus() (dbx) print proc[i+2] proc[i+2] = 0xff25c694 = &XFilterEvent() Can someone from Java group please evaluate this? I tried using a debug build of java, but could not get it to work. ============================================================================== I looked at all the code in Java that calls XCheckIfEvent and I did find that in one case, we DO call X from the predicate function. This happens in awt_TopLevel.c Lines 1227 onwards: // This window lost focus. Find the opposite window which will // receive it XCheckIfEvent(awt_display, &inEvent, check_for_focus_in, (XPointer)&focus_info); if (focus_info.inWin != None) { And the check_for_focus_in function does indeed call X11 : static Bool check_for_focus_in(Display * dpy, XEvent * eve
24-08-2004

WORK AROUND Name: pa48320 Date: 08/19/2003 None ======================================================================
24-08-2004

EVALUATION nt, XPointer data) { FocusOutInfo_t * prev = (FocusOutInfo_t *)data; JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); if (event->type == FocusIn && event->xfocus.serial == prev->eventOut->xfocus.serial && event->xfocus.mode == prev->eventOut->xfocus.mode) { Widget w = NULL; jobject wpeer = NULL; jboolean exc; w = XtWindowToWidget(awt_display, event->xfocus.window); if (w != NULL) { if (!isTopLevelPartWidget(w)) { if (prev->inChild != None && prev->childComp == NULL) { So I commented the call to XCheckIfEvent and sure enough the app does not hang any more. So I guess the culprit is AWT. Looks like we will have to redo this code. It looks like Focus specific code. I will reassign to AWT. Sorry for the run-around, Jeremy's comments were very helpful. ###@###.### 2004-01-09 Name: dfR10261 Date: 01/28/2004 On Solaris The application hungs in native setNativeFontPath() function. Further investigation shows that application hungs in Xlib function XQueryExtension. Hung happens then LockDisplay(dpy) is invoked. I have tried to comment this macros in case of Display was already locked. After it application hungs then _XReply (dpy, (xReply *)&rep, 0, xTrue) was invoked. ###@###.### 2004-01-28 ====================================================================== On Solaris 5.8, I am seeing the hang in XtDisplayInitialize() called in Java_sun_awt_motif_MToolkit_init(). XtDisplayInitialize() internally makes call to XInterAtom() and that's where the process hangs. The output of truss attached to jnitest: .... .... /1: <- libXt:XtAppSetFallbackResources() = 0x1bb5f0 /1: -> libXt:XtDisplayInitialize(0x1bb5f0, 0x98d30, 0xfb864118, 0xfb864128) /1: -> libX11:XCreateRegion(0x11da0c, 0xe6a74000, 0x98d30, 0x0) /1: <- libX11:XCreateRegion() = 0x1ba460 /1: -> libX11:XDisplayKeycodes(0x98d30, 0x11d9c4, 0x11d9c8, 0x0) /1: <- libX11:XDisplayKeycodes() = 0x98d30 /1: -> libX11:XrmStringToQuark(0xfb864118, 0x11d9c4, 0x11d9c8, 0x0) /1: -> libX11:_XrmInternalStringToQuark(0xfb864118, 0xc, 0x56df4, 0x0) /1: <- libX11:XrmStringToQuark() = 201 /1: -> libX11:XrmStringToQuark(0xfb864128, 0xc9, 0xfb864124, 0x80000000) /1: -> libX11:_XrmInternalStringToQuark(0xfb864128, 0xc, 0x57d40, 0x0) /1: <- libX11:XrmStringToQuark() = 202 /1: -> libX11:XInternAtom(0x98d30, 0xe6a5f500, 0x0, 0x80000000) .......hangs here........ I generated the truss output with 1.3.1 also and the difference I notice here is that there is no XQueryExtension call made in 1.3.1 trace. ###@###.### 2004-01-28 ============================================================ The stack trace at the time of hang is: libX11:_XReply(0x96db0, 0xffbed254, 0x0, 0x1) libX11:XInternAtom (dpy, RCM_INIT, 0) <<====================== libXt:InitPerDisplay(0x96db0, 0x173c40, 0x172180, 0x172180) libXt:XtDisplayInitialize(0x173c40, 0x96db0, 0x172180, 0x172180) The libX11:XInternAtom call made with the atom name "RCM_INIT" is waiting for reply from the X server which is never receives. The code in libXt:InitPerDisplay() which is making call to XInternAtom is as follows: #ifndef X_NO_RESOURCE_CONFIGURATION_MANAGEMENT pd->rcm_init = XInternAtom (dpy, RCM_INIT, 0); pd->rcm_data = XInternAtom (dpy, RCM_DATA, 0); #endif ***** As I mentioned in my previous update that there is an XQueryExtension call being made from 142 JDK code that I don't see in the truss output of 131. I tracked down that this call was being made from isDBESupported() in awt_GraphicsEnv.c. I commented out this code and with this change the 1.4.2 build also works fine. I don't see any hang after this modification. I still don't know the reason behind it. Probably the way we are making this call is not correct. ###@###.### 2004-01-29 Name: dfR10261 Date: 01/29/2004 Then I use 1.5 on Solaris application hungs in X11GraphicsEnvironment.setNativeFontPath() in static initialize block of MToolkit. After I comment this invocation application hungs in XtDisplayInitialize() which called in Java_sun_awt_motif_MToolkit_init(). After I comment XtDisplayInitialize() invocation hung occurs on XmGetFocusWidget() in check_for_focus_in() function in awt_TopLevel.c ###@###.### 2004-01-29 ====================================================================== ###@###.### 2004-01-29 There appears to be two seperate bugs here: 1. XCheckIfEvents() is called from Java with check_for_focus_in as the predicate and this function calls Xlib calls which are not allowed by the predicate. 2. Another bug is causing hangs at different places in Xlib. I think that the cause of this bug is due to some issues with XdbeGetVisualInfo(). I have filed bug 4985837: XdbeGetVisualInfo causes Xlib threads to hang In order to continue working on the first bug with XCheckIfEvents(), I have attached a test libX11 for Solaris 8 sparc which unofficially fixes bug 4985837. Please escalate bug 4985837 if fix for this bug is still needed after fixing XCheckIfEvents() predicate problem. ====================================================== I ran the testcase using the libX11.so given by Jeremy on solaris 5.8. It removes the hang at XtDisplayInitialize(): * when run using local display the testcase does not hang at all, neither in XtDisplayInitialize() nor in XCheckIfEvents. * When run using remote display, it hangs in XCheckIfEvents. Now the solution for the problem would be to remove XmGetFocusWidget() call from check_for_focus_in and use the cached data instead to get the window that has the keybord focus. ###@###.### 2004-01-30 ====================================================== The predicate of XCheckIfEvent, check_for_focus_in(), always returns False even when it finds the matching FocusIn event. XCheckIfEvent calls predicate procedure for all the events in the queue until it returns True. So in our case, even after finding the mactched event, it gets called for the rest of the events also, as we are always returning False. It may cause performance degradation. Probably this was done so as not to remove the FocusIn event from the queue(when predicate returns True, XCheckIfEvent removes the event from the queue), but this can be tackled by using XPutBackEvent which puts the event back into queue. So the correct way should be to return True in predicate when we have found the match and process the FocusIn event after the XCheckIfEvent call. I tested jnitest, after doing the above mentioned modifications in awt_TopLevel.c and it works fine without any hang. ###@###.### 2004-02-03 Fix verified for build 1.4.2_05-ea-b01 on WinXP Home and RHEl 3 on Itanium Raja Dhanesh ###@###.### 2004-04-29
03-02-2004