Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 317902

Summary: Segmentation Fault When Widget looses focus
Product: [Eclipse Project] Platform Reporter: Kris De Volder <kdevolder>
Component: SWTAssignee: Felipe Heidrich <eclipse.felipe>
Status: RESOLVED FIXED QA Contact:
Severity: critical    
Priority: P3 CC: andrew.eisenberg, eclipse.felipe, jaroslav.resler, mseele, pwebster, remy.suen, Silenio_Quarti
Version: 3.6Flags: Silenio_Quarti: review+
Target Milestone: 3.6.1   
Hardware: PC   
OS: Linux-GTK   
Whiteboard:
Attachments:
Description Flags
crahs log
none
Snippet that shows the bug
none
patch which fiexs the problem
none
patch for HEAD none

Description Kris De Volder CLA 2010-06-24 20:30:55 EDT
See related bug report in STS issue tracker:

https://issuetracker.springsource.com/browse/STS-1046

The bug is 100% reproducible on my machine, with my currently installed development setup. Unfortunately the example is bound up with a lot of dependencies to STS components.

This behavior started appearing when I switched to Eclipse 3.6 today. It did not happen in Eclipse 3.5.

I also submitted a bugreport to Sun, but later realized this is much more likely an issue with SWT native libraries for the linux platform. I tried the same sequence of steps on windows and mac, and it only happens on Linux.

Crash log is attached.
Comment 1 Kris De Volder CLA 2010-06-24 22:39:54 EDT
Created attachment 172703 [details]
crahs log

Thought I already attached this, but seems I didn't.
Comment 2 Kris De Volder CLA 2010-06-27 01:17:14 EDT
I've got some more info which may help. I am still able to reproduce this bug 100% accurately.

This sad in a sense, since I'm trying to find a workaround...

But it also gives me a chance to try and track down where exactly it happens.

I can put a breakpoint in an eventlistener just before the bug happens and then a few steps backing out of the stack and into an event dispatch brings me here:

Thread [main] (Suspended (breakpoint at line 753 in Shell))	
	Shell.filterProc(int, int, int) line: 753	
	Display.filterProc(int, int, int) line: 1537	
	OS._g_main_context_iteration(int, boolean) line: not available [native method]	
	OS.g_main_context_iteration(int, boolean) line: 2224	
	Display.readAndDispatch() line: 3169	
	Workbench.runEventLoop(Window$IExceptionHandler, Display) line: 2629	
	Workbench.runUI() line: 2593	
	Workbench.access$4(Workbench) line: 2427	
	Workbench$7.run() line: 670	
	Realm.runWithDefault(Realm, Runnable) line: 332	
	Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 663	
	PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 149	
	IDEApplication.start(IApplicationContext) line: 115	
	EclipseAppHandle.run(Object) line: 196	
	EclipseAppLauncher.runApplication(Object) line: 110	
	EclipseAppLauncher.start(Object) line: 79	
	EclipseStarter.run(Object) line: 369	
	EclipseStarter.run(String[], Runnable) line: 179	
	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39	
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25	
	Method.invoke(Object, Object...) line: 597	
	Main.invokeFramework(String[], URL[]) line: 619	
	Main.basicRun(String[]) line: 574	
	Main.run(String[]) line: 1407	
	Main.main(String[]) line: 1383	

The version of the Jar this stacktrace originates in is:
/home/kdvolder/Applications/springsource/sts-2.3.3.201006180757/plugins/org.eclipse.swt.gtk.linux.x86_3.6.0.v3650b.jar

An what I'm seeing there (looking at it right now) is this code:

		case OS.FocusOut:
			if (xFocusEvent.mode == OS.NotifyNormal || xFocusEvent.mode == OS.NotifyWhileGrabbed) {
				switch (xFocusEvent.detail) {
					case OS.NotifyNonlinear:
					case OS.NotifyNonlinearVirtual:
					case OS.NotifyVirtual:
						if (tooltipsHandle != 0) OS.gtk_tooltips_disable (tooltipsHandle);
						Display display = this.display;
						sendEvent (SWT.Deactivate);
						setActiveControl (null);
						if (display.activeShell == this) {
							display.activeShell = null;
							display.activePending = false;
						}
						if (isCustomResize ()) {
=== HERE ===>   	        OS.gdk_window_invalidate_rect (OS.GTK_WIDGET_WINDOW (shellHandle), null, false);
						}
						break;
				}
			}
			break;

And in the variables of the debugger, I can see that the "this" pointer of this Shell displays as

Shell {*Disposed*}

Then, when we step this line: 
   OS.gdk_window_invalidate_rect (OS.GTK_WIDGET_WINDOW (shellHandle), null, false)
   
=> KABOOM!
Comment 3 Kris De Volder CLA 2010-06-27 01:36:32 EDT
In case this helps as well, this the stack at the point where I put the breakpoint. It's inside a listener that wants to be notified of deactivation of a popup style window/widget (like content assist in Eclipse). 

Thread [main] (Suspended (breakpoint at line 1088 in GrailsInplaceDialog$11))	
	GrailsInplaceDialog$11.proposalPopupClosed(ContentProposalAdapter) line: 1088	
	ContentProposalAdapter.notifyPopupClosed() line: 2119	
	ContentProposalAdapter.access$8(ContentProposalAdapter) line: 2112	
	ContentProposalAdapter$ContentProposalPopup.close() line: 916	
	ContentProposalAdapter$ContentProposalPopup$PopupCloserListener.handleEvent(Event) line: 132	
	EventTable.sendEvent(Event) line: 84	
	Shell(Widget).sendEvent(Event) line: 1258	
	Shell(Widget).sendEvent(int, Event, boolean) line: 1282	
	Shell(Widget).sendEvent(int) line: 1263	
	Shell.filterProc(int, int, int) line: 746	
	Display.filterProc(int, int, int) line: 1537	
	OS._g_main_context_iteration(int, boolean) line: not available [native method]	
	OS.g_main_context_iteration(int, boolean) line: 2224	
	Display.readAndDispatch() line: 3169	
	Workbench.runEventLoop(Window$IExceptionHandler, Display) line: 2629	
	Workbench.runUI() line: 2593	
	Workbench.access$4(Workbench) line: 2427	
	Workbench$7.run() line: 670	
	Realm.runWithDefault(Realm, Runnable) line: 332	
	Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 663	
	PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 149	
	IDEApplication.start(IApplicationContext) line: 115	
	EclipseAppHandle.run(Object) line: 196	
	EclipseAppLauncher.runApplication(Object) line: 110	
	EclipseAppLauncher.start(Object) line: 79	
	EclipseStarter.run(Object) line: 369	
	EclipseStarter.run(String[], Runnable) line: 179	
	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39	
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25	
	Method.invoke(Object, Object...) line: 597	
	Main.invokeFramework(String[], URL[]) line: 619	
	Main.basicRun(String[]) line: 574	
	Main.run(String[]) line: 1407	
	Main.main(String[]) line: 1383	

When I am at this breakpoint I can see that the shell is already disposed...

Let me know if I can do some more digging (before I figure out a workaround and won't be able to reproduce this anymore :-)
Comment 4 Kris De Volder CLA 2010-06-27 02:04:59 EDT
One more stacktrace, this one points to the actual call to Shell.dispose that causes the shell to be disposed.

Thread [main] (Suspended (breakpoint at line 2236 in Shell))	
	Shell.dispose() line: 2236	
	ContentProposalAdapter$ContentProposalPopup(Window).close() line: 335	
	ContentProposalAdapter$ContentProposalPopup(PopupDialog).close() line: 1191	
	ContentProposalAdapter$ContentProposalPopup.close() line: 915	
	ContentProposalAdapter$ContentProposalPopup$PopupCloserListener.handleEvent(Event) line: 132	
	EventTable.sendEvent(Event) line: 84	
	Shell(Widget).sendEvent(Event) line: 1258	
	Shell(Widget).sendEvent(int, Event, boolean) line: 1282	
	Shell(Widget).sendEvent(int) line: 1263	
	Shell.filterProc(int, int, int) line: 746	
	Display.filterProc(int, int, int) line: 1537	
	OS._g_main_context_iteration(int, boolean) line: not available [native method]	
	OS.g_main_context_iteration(int, boolean) line: 2224	
	Display.readAndDispatch() line: 3169	
	Workbench.runEventLoop(Window$IExceptionHandler, Display) line: 2629	
	Workbench.runUI() line: 2593	
	Workbench.access$4(Workbench) line: 2427	
	Workbench$7.run() line: 670	
	Realm.runWithDefault(Realm, Runnable) line: 332	
	Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 663	
	PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 149	
	IDEApplication.start(IApplicationContext) line: 115	
	EclipseAppHandle.run(Object) line: 196	
	EclipseAppLauncher.runApplication(Object) line: 110	
	EclipseAppLauncher.start(Object) line: 79	
	EclipseStarter.run(Object) line: 369	
	EclipseStarter.run(String[], Runnable) line: 179	
	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39	
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25	
	Method.invoke(Object, Object...) line: 597	
	Main.invokeFramework(String[], URL[]) line: 619	
	Main.basicRun(String[]) line: 574	
	Main.run(String[]) line: 1407	
	Main.main(String[]) line: 1383
Comment 5 Kris De Volder CLA 2010-06-27 03:33:58 EDT
I have got a fix / workaround here.

We can wrap the call to close from handle event
At stacktrace line:
ContentProposalAdapter$ContentProposalPopup$PopupCloserListener.handleEvent(Event)

in a call to async exec like so

	// For all other events, merely getting them dictates closure.
        /* STS Change: new code: */
	e.display.asyncExec(new Runnable() {
	    public void run() {
	    close(); 
					}
				});
				/* STS Change: old code: 
				close();
				*/
Comment 6 Kris De Volder CLA 2010-06-27 03:45:19 EDT
Sorry that got a bit messed up (why is this darned text layout contrained to so few colums?)

//Change at line: 132
//Class: org.eclipse.jface.fieldassist.ContentProposalAdapter
//Version of the jar: org.eclipse.jface_3.6.0.I20100601-0800.jar

  // For all other events, merely getting them dictates closure.
  /* STS Change: new code: */
  e.display.asyncExec(new Runnable() {
      public void run() {
         close(); 
      }
  });
  /* STS Change: old code: (line 132)
  close();
  */
Comment 7 Michael Seele CLA 2010-07-08 05:07:31 EDT
Created attachment 173751 [details]
Snippet that shows the bug

i can also reproduce this bug. I've wrote a snippet that shows the bug. 

Please execute the snippet, set focus to text field. Press space key to show proposal adapter, then click into proposal adapter to get them the focus. If you now click into the shell, vm crashes.
Comment 8 Michael Seele CLA 2010-07-08 05:50:49 EDT
Created attachment 173755 [details]
patch which fiexs the problem

I've investigated something around this bug:

- #23980 opens this bug
- the crash is, like kris said before, in Shell:753. gdk_window_invalidate_rect is made on a disposed shell
- i've added a patch which fixes the bug by checking the shell disposed state
Comment 9 Felipe Heidrich CLA 2010-07-08 16:41:45 EDT
*** Bug 319119 has been marked as a duplicate of this bug. ***
Comment 10 Remy Suen CLA 2010-07-09 08:44:29 EDT
These are the steps we believe should reproduce the problem in a regular Eclipse SDK without additional plug-ins.

1) From a java editor, I open CTRL+F.
2) check regular expressions
3) Invoke Ctrl+Space in the 'Find' text field.
4) Click on an entry in the popup, but don't double click
5) Click inside the editor in the "background".
Comment 11 Jaroslav Resler CLA 2010-08-06 04:15:29 EDT
When will be Michaels patch available in eclipse updates? This is a critical bug causing eclipse to be unsuitable for regular work.
Comment 12 Felipe Heidrich CLA 2010-08-06 16:05:56 EDT
Created attachment 176067 [details]
patch for HEAD

Michaels was right on the money, the shell was being disposed by the deactive event handler. thanks for the test case and the fix.

Fixed in HEAD > 20100806
Comment 13 Felipe Heidrich CLA 2010-08-06 16:10:04 EDT
Silenio, please review for 3.6.1
Comment 14 Felipe Heidrich CLA 2010-08-06 16:10:48 EDT
Note: the patch for HEAD is good for the R3_6_maintenance stream as well.
Comment 15 Felipe Heidrich CLA 2010-08-06 16:17:02 EDT
Fixed in R3_6_maintenance > 2010-08-06