Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 378846 - Eclipse Crashes while clicking button when a table has the focus
Summary: Eclipse Crashes while clicking button when a table has the focus
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.8   Edit
Hardware: Macintosh Mac OS X - Carbon (unsup.)
: P3 critical (vote)
Target Milestone: 4.2 RC2   Edit
Assignee: Lakshmi P Shanmugam CLA
QA Contact: Silenio Quarti CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-05-08 10:41 EDT by Galileo Perez CLA
Modified: 2013-12-11 05:52 EST (History)
8 users (show)

See Also:
gheorghe: review+
grant_gayed: review+


Attachments
snippet (1.83 KB, application/octet-stream)
2012-05-14 15:14 EDT, Lakshmi P Shanmugam CLA
no flags Details
crash log-1 (103.92 KB, text/rtf)
2012-05-14 15:22 EDT, Lakshmi P Shanmugam CLA
no flags Details
work in progress patch (1.23 KB, patch)
2012-05-21 09:58 EDT, Lakshmi P Shanmugam CLA
no flags Details | Diff
patch-2 (1.09 KB, patch)
2012-05-22 08:39 EDT, Lakshmi P Shanmugam CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Galileo Perez CLA 2012-05-08 10:41:11 EDT
Build Identifier: I20120314-1800

When using WTP project over Eclipse 3.8 on Mac OS X, and editing the values from Deployment Assembly Deploy Path on the Deployment Assembly page, Eclipse crashes if the table cell still on editing mode and Revert, OK or Cancel button is pressed.

Reproducible: Always

Steps to Reproduce:
1.Install WTP on Eclipse 3.8
2.Create an Web Dynamic project
3.Right click on the project and select Deployment Assembly option.
4.Click on one of the cells from the Deploy Path and let the cell on editing mode(do not click anywhere else)
5.Click one of the following buttons (Revert, OK, Cancel)
Comment 1 Chuck Bridgham CLA 2012-05-10 10:14:30 EDT
Stack trace info:

Current thread (104801000):  JavaThread "main" [_thread_in_native, id=1953175904, stack(7fff5f400000,7fff5fc00000)]
Stack: [7fff5f400000,7fff5fc00000]
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J  org.eclipse.swt.internal.cocoa.OS.object_getInstanceVariable(J[B[J)J
J  org.eclipse.swt.widgets.Display.getWidget(J)Lorg/eclipse/swt/widgets/Widget;
j  org.eclipse.swt.widgets.Tree.getTopItem()Lorg/eclipse/swt/widgets/TreeItem;+79
j  org.eclipse.jface.viewers.TreeViewerFocusCellManager.getInitialFocusCell()Lorg/eclipse/jface/viewers/ViewerCell;+26
j  org.eclipse.jface.viewers.SWTFocusCellManager.handleFocusIn(Lorg/eclipse/swt/widgets/Event;)V+9
j  org.eclipse.jface.viewers.SWTFocusCellManager.access$3(Lorg/eclipse/jface/viewers/SWTFocusCellManager;Lorg/eclipse/swt/widgets/Event;)V+2
j  org.eclipse.jface.viewers.SWTFocusCellManager$2.handleEvent(Lorg/eclipse/swt/widgets/Event;)V+86
J  org.eclipse.swt.widgets.EventTable.sendEvent(Lorg/eclipse/swt/widgets/Event;)V
j  org.eclipse.swt.widgets.Display.sendEvent(Lorg/eclipse/swt/widgets/EventTable;Lorg/eclipse/swt/widgets/Event;)V+24
j  org.eclipse.swt.widgets.Widget.sendEvent(Lorg/eclipse/swt/widgets/Event;)V+9
j  org.eclipse.swt.widgets.Widget.sendEvent(ILorg/eclipse/swt/widgets/Event;Z)V+73
j  org.eclipse.swt.widgets.Widget.sendEvent(I)V+4
j  org.eclipse.swt.widgets.Control.sendFocusEvent(I)V+22
j  org.eclipse.swt.widgets.Display.checkFocus()V+51
j  org.eclipse.swt.widgets.Shell.makeFirstResponder(JJJ)Z+26
j  org.eclipse.swt.widgets.Display.windowProc(JJJ)J+1522
v  ˜StubRoutines::call_stub
j  org.eclipse.swt.internal.cocoa.OS.objc_msgSend_bool(JJJ)Z+0
j  org.eclipse.swt.internal.cocoa.NSWindow.makeFirstResponder(Lorg/eclipse/swt/internal/cocoa/NSResponder;)Z+19
j  org.eclipse.swt.widgets.Control.forceFocus(Lorg/eclipse/swt/internal/cocoa/NSView;)Z+16
j  org.eclipse.swt.widgets.Control.forceFocus()Z+81
j  org.eclipse.swt.widgets.Control.setFocus()Z+18
j  org.eclipse.swt.widgets.Composite.setFocus()Z+35
j  org.eclipse.swt.widgets.Control.fixFocus(Lorg/eclipse/swt/widgets/Control;)V+11
j  org.eclipse.swt.widgets.Control.setVisible(Z)V+159
j  org.eclipse.jface.viewers.CellEditor.deactivate()V+22
j  org.eclipse.jface.viewers.CellEditor.deactivate(Lorg/eclipse/jface/viewers/ColumnViewerEditorDeactivationEvent;)V+1
j  org.eclipse.jface.viewers.ColumnViewerEditor.cancelEditing()V+198
j  org.eclipse.jface.viewers.ColumnViewerEditor$1.widgetDisposed(Lorg/eclipse/swt/events/DisposeEvent;)V+14
Comment 3 Galileo Perez CLA 2012-05-10 10:23:36 EDT
Hi Platform SWT team, 
Do you have any update regarding this item?, it's really important to get solved this defect since crashes the tool.


Regards
Comment 4 Lakshmi P Shanmugam CLA 2012-05-11 06:27:03 EDT
(In reply to comment #3)
I can reproduce the crash with WTP using the above steps. The problem is similar to Bug 326311, Display.getWidget() is getting called with id of disposed TreeItem which causes the crash.
Comment 5 Lakshmi P Shanmugam CLA 2012-05-14 15:14:15 EDT
Created attachment 215595 [details]
snippet

I debugged this further. When the Tree is being disposed, we dispose the TreeItems and their handle is released, but NSOutlineView is not updated. So, when tree.getTopItem() is called in the each TreeItem's dispose listener, it returns the handle of the first item each time, but the handle is no longer valid.

attached is a snippet showing similar problem.
Comment 6 Lakshmi P Shanmugam CLA 2012-05-14 15:22:17 EDT
Created attachment 215596 [details]
crash log-1

Also, the crash happens with different stack traces. This is different from comment 1
Comment 7 Lakshmi P Shanmugam CLA 2012-05-14 16:32:34 EDT
Hi Silenio,
I tried to use item.release(true) instead of release(false) in Tree.releaseChildren() and Tree.removeAll() so that the tree is updated after each item is disposed.

       for (int i=0; i<items.length; i++) {
-		TreeItem item = items [i];
+		TreeItem item = items [0];
 		if (item != null && !item.isDisposed ()) {
-			item.release (false);
+			item.release (true);
 		}
 	}

This seems to fix the problem (based on limited testing). But, I'm not sure why the existing code uses release(false) instead of release(true)?
Comment 8 Galileo Perez CLA 2012-05-17 16:46:52 EDT
Hi, is there any update? Regards
Comment 9 Lakshmi P Shanmugam CLA 2012-05-21 09:58:24 EDT
Created attachment 215963 [details]
work in progress patch

The patch tries to fix the 2 crashes happening in this particular case. It prevents the Tree from getting focus when all its items are being disposed. Hence, getTopItem() is not called.
But it doesn't fix the problem with getTopItem() in general.

I'm testing the patch to see if it causes any new problems.
Comment 10 Lakshmi P Shanmugam CLA 2012-05-22 08:39:41 EDT
Created attachment 216025 [details]
patch-2

This patch updates the Tree in removeAll() and releaseChildren() before releasing the items. This is similar to what we do in setItemCount().
I have tested the patch and it fixes the crashes.
Comment 11 Lakshmi P Shanmugam CLA 2012-05-22 08:43:18 EDT
Hi Bogdan & Grant,
Can you please review the patch-2 and let me know your comments? 
Thanks!
Comment 12 Grant Gayed CLA 2012-05-22 17:04:23 EDT
Clearing the tree's content sooner does not seem like a good thing to do because clients expect a Control's/Item's state to still be intact when a Dispose event is received for it.  For instance, if the content of the DisposeListener was changed to the following then the platform inconsistency that this would introduce becomes more clear:

// (add a static "counter" var)
if (counter++ == 5) {
	TreeItem[] items = tree.getItems();
	for (int i = 0; i < items.length; i++) {
		System.out.println(items[i]);
	}
}

If I understand the problem correctly, getTopItem() is answering item 0 after it has been disposed because this item still physically resides at location 0,0.  So this seems like an issue particular to getTopItem() rather than something that pervades Tree.  Is a comparatively more local fix possible?
Comment 13 Lakshmi P Shanmugam CLA 2012-05-23 07:53:13 EDT
(In reply to comment #12)
> Clearing the tree's content sooner does not seem like a good thing to do
> because clients expect a Control's/Item's state to still be intact when a
> Dispose event is received for it.  For instance, if the content of the
> DisposeListener was changed to the following then the platform inconsistency
> that this would introduce becomes more clear:
> 
I agree that this would be a platform inconsistency. But it already exists, we already do this in Tree code in Tree.setItemCount(TreeItem, int) which I believe is for the same reason (to prevent a crash).

> If I understand the problem correctly, getTopItem() is answering item 0 after
> it has been disposed because this item still physically resides at location
> 0,0.  So this seems like an issue particular to getTopItem() rather than
> something that pervades Tree.  Is a comparatively more local fix possible?
The problem is that NSOutlineView.itemAtRow() returns the id of the item which is already released because the tree is not updated. It is not particular to getTopItem(), it can happen with getSelection() or getItem() too if they are called from TreeItem's widgetDisposed listener in a similar way.
So, I think we should try to fix the underlying problem of the NSOutlineView having handles to disposed items.
Comment 14 Lakshmi P Shanmugam CLA 2012-05-23 08:27:13 EDT
(In reply to comment #12)
> Clearing the tree's content sooner does not seem like a good thing to do
> because clients expect a Control's/Item's state to still be intact when a
> Dispose event is received for it.  For instance, if the content of the
> DisposeListener was changed to the following then the platform inconsistency
> that this would introduce becomes more clear:
> 
> // (add a static "counter" var)
> if (counter++ == 5) {
>     TreeItem[] items = tree.getItems();
>     for (int i = 0; i < items.length; i++) {
>         System.out.println(items[i]);
>     }
> }
> 
I was thinking we could also modify the patch such that we save the itemCount and reset it after the Tree is updated. So, the code in DisposeListener could still access the items from the items array and we avoid platform inconsistency.
int count = itemCount;
itemCount = 0;
((NSOutlineView) view).reloadData ();
itemCount = count;
Comment 15 Grant Gayed CLA 2012-05-23 16:09:33 EDT
Comment 14 is an improvement, I've committed it with a little modification, patch: http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?h=R3_8_maintenance&id=d7fab8bf9eb7250e6125d7b69fdbdc31ee05e52e .
Comment 16 Lakshmi P Shanmugam CLA 2012-05-24 11:10:47 EDT
The crashes are fixed but a NPE is caused in TreeViewerFocusCellManager at if (! tree.isDisposed() && tree.getItemCount() > 0 && ! tree.getTopItem().isDisposed()) because tree.getTopItem() returns null but tree.getItemCount() is not 0.

I'll revert the fix to patch in comment#10.
Comment 18 Lakshmi P Shanmugam CLA 2012-05-25 08:26:44 EDT
Verified in 4.2 build I20120524-2100
Comment 19 Silenio Quarti CLA 2012-05-29 17:02:35 EDT
I created bug#380966 with an alternative patch for this bug.  That patch fixes the platform inconsistency caused by this fix (comment#12).

We will consider the patch after 3.8/4.2 ships.
Comment 20 Laurent Redor CLA 2013-12-11 05:52:31 EST
Lakshmi, in your comment #16, you speak about a NPE. I think that my problem [1] is probably link to this.

Could you have a look on this post?

[1] http://www.eclipse.org/forums/index.php/mv/msg/560710/1220344/#msg_1220344