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

Bug 335193

Summary: NullPointerException raised by ModelContentProvider.cancelRestore
Product: [Eclipse Project] Platform Reporter: Winnie Lai <wlai>
Component: DebugAssignee: Pawel Piech <pawel.1.piech>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: Michael_Rennie, pawel.1.piech
Version: 3.7Flags: Michael_Rennie: review+
Target Milestone: 3.7 M6   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
patch of null pointer exception (not used) pawel.1.piech: iplog-

Description Winnie Lai CLA 2011-01-24 09:47:25 EST
Build Identifier: 3.7 m4 I20101208-1300

Here is the call stack when model content provider is called to cancel restoring state,

Caused by: java.lang.NullPointerException
 at org.eclipse.debug.internal.ui.viewers.model.ModelContentProvider.cancelRestore(ModelContentProvider.java:524)
 at org.eclipse.debug.internal.ui.viewers.model.InternalTreeModelViewer.handleSelect(InternalTreeModelViewer.java:2458)
 at org.eclipse.jface.viewers.StructuredViewer$4.widgetSelected(StructuredViewer.java:1220)
 at org.eclipse.jface.util.OpenStrategy.fireSelectionEvent(OpenStrategy.java:229)
 at org.eclipse.jface.util.OpenStrategy.access$4(OpenStrategy.java:223)
 at org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrategy.java:393)
 at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
 at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1258)


Looking at the code, both lines 524 and 541 of this method need to be safe-guarded by a check of fPendingState before calling fPendingState.accept.accept(...).

Reproducible: Always
Comment 1 Winnie Lai CLA 2011-01-24 10:21:55 EST
This problem is common to any debug related views that use ModelContentProvider to save and restore expansion states.


Steps to reproduce,
1. Open a register view that can show structures. In my test case, I have a register view that has groups, and each group has registers. 
2. Launch a debugger. Select an element of debug view so that the register view shows the groups and registers. I exapnd each node of register view to show all elements.
3. Click another node of debug view so that the register view no longer shows the content from step 2.
4. Click back the node in debug view at step 2 so that the register view is restoring its expansion states in step 2. Just before the register view finishes its restoration, collapse a register group in register view. The ModelContentProvider.cancelRestore is called at this point and a null pointer exception is throw as shown in the call stack.
Comment 2 Winnie Lai CLA 2011-01-24 10:29:38 EST
Created attachment 187430 [details]
patch of null pointer exception (not used)

In cancelRestore(), added code to check whether fPendingState is a null pointer before using fPendingState.accept().
Comment 3 Pawel Piech CLA 2011-01-26 11:16:19 EST
I'd like to reproduce this with a unit test.
Comment 4 Pawel Piech CLA 2011-02-17 18:41:29 EST
It took me a while, but I managed to reproduce the problem in a unit test.  I also found another (minor) issue where the restore delta was not being cleared after a cancelRestore().  This bug was introduced by a fix for bug 324100, so it never shipped in a release.

Winnie, please verify the fix.
Comment 5 Winnie Lai CLA 2011-02-18 09:56:32 EST
The fix runs ok with my test case. Thanks.
Comment 6 Michael Rennie CLA 2011-02-24 12:10:18 EST
verified. 

I added an update to InternalTreeModelViewer#handleSelect where we should be passing in the flags SELECT | REVEAL to cancelRestore instead of just SELECT. Chatting with Pawel, we felt this makes sense, in case a pending restore will try to select a new top item, this will cause the fPendingSetTopItem delta to be disposed.