This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 172060 - dbx: AssertionError on changing variable value
Summary: dbx: AssertionError on changing variable value
Status: RESOLVED FIXED
Alias: None
Product: third-party
Classification: Unclassified
Component: DBX-Gui (show other bugs)
Version: 6.x
Hardware: All All
: P2 blocker (vote)
Assignee: ivan
URL:
Keywords: REGRESSION
Depends on: 172694
Blocks:
  Show dependency tree
 
Reported: 2009-09-11 17:45 UTC by Alexander Pepin
Modified: 2009-10-31 01:53 UTC (History)
2 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alexander Pepin 2009-09-11 17:45:24 UTC
Steps to reproduce:
- create Welcome sample
- set SS compiler collection
- set Line BP inside "for" loop
- start debugger
- when it stops at BP open Variables window
- change the value of variable "i" to 4 then press "Enter" 
Result: The value is not changed. Exception window appears:
java.lang.AssertionError
	at com.sun.tools.debugger.dbxgui.debugger.dbx.CommonDbx.sendCommandHelp(CommonDbx.java:1103)
	at com.sun.tools.debugger.dbxgui.debugger.dbx.Dbx.sendCommandHelp(Dbx.java:251)
	at com.sun.tools.debugger.dbxgui.debugger.dbx.Dbx.sendCommand(Dbx.java:280)
	at com.sun.tools.debugger.dbxgui.debugger.dbx.DbxDebuggerImpl.execute(DbxDebuggerImpl.java:1302)
	at com.sun.tools.debugger.dbxgui.debugger.dbx.DbxVariable.setVariableValue(DbxVariable.java:197)
	at com.sun.tools.debugger.dbxgui.debugger.VariableModel.setValueAt(VariableModel.java:331)
	at org.netbeans.spi.viewmodel.Models$DelegatingTableModel.setValueAt(Models.java:1698)
	at org.netbeans.spi.viewmodel.Models$CompoundModel.setValueAt(Models.java:3358)
	at org.netbeans.modules.debugger.ui.views.ViewModelListener$UnionTreeModel.setValueAt(ViewModelListener.java:1303)
	at org.netbeans.spi.viewmodel.Models$DelegatingTableModel.setValueAt(Models.java:1698)
	at org.netbeans.spi.viewmodel.Models$CompoundModel.setValueAt(Models.java:3358)
	at org.netbeans.modules.viewmodel.TreeModelNode$MyProperty$1.run(TreeModelNode.java:1190)
	at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:602)
	at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:1070)
Caused: org.openide.util.RequestProcessor$SlowItem: task failed due to
	at org.openide.util.RequestProcessor.post(RequestProcessor.java:292)
	at org.netbeans.modules.viewmodel.TreeModelNode$MyProperty.setValue(TreeModelNode.java:1186)
	at org.openide.explorer.propertysheet.NodePropertyModel.setValue(NodePropertyModel.java:110)
	at org.openide.explorer.propertysheet.PropUtils.noDlgUpdateProp(PropUtils.java:566)
	at org.openide.explorer.propertysheet.EditablePropertyDisplayer._commit(EditablePropertyDisplayer.java:208)
	at org.openide.explorer.propertysheet.EditablePropertyDisplayer.commit(EditablePropertyDisplayer.java:129)
	at
org.openide.explorer.propertysheet.EditablePropertyDisplayer$InplaceEditorListener.actionPerformed(EditablePropertyDisplayer.java:808)
	at javax.swing.JTextField.fireActionPerformed(JTextField.java:492)
	at javax.swing.JTextField.postActionEvent(JTextField.java:705)
	at javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:820)
	at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1636)
	at javax.swing.JComponent.processKeyBinding(JComponent.java:2851)
	at javax.swing.JComponent.processKeyBindings(JComponent.java:2886)
	at javax.swing.JComponent.processKeyEvent(JComponent.java:2814)
	at java.awt.Component.processEvent(Component.java:6040)
	at java.awt.Container.processEvent(Container.java:2041)
	at java.awt.Component.dispatchEventImpl(Component.java:4630)
	at java.awt.Container.dispatchEventImpl(Container.java:2099)
	at java.awt.Component.dispatchEvent(Component.java:4460)
	at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
	at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:704)
	at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:969)
	at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:841)
	at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:668)
	at java.awt.Component.dispatchEventImpl(Component.java:4502)
	at java.awt.Container.dispatchEventImpl(Container.java:2099)
	at java.awt.Window.dispatchEventImpl(Window.java:2475)
	at java.awt.Component.dispatchEvent(Component.java:4460)
[catch] at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:117)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Comment 1 Vladimir Voskresensky 2009-09-15 10:25:54 UTC
This is the regression caused by a trick made in
http://hg.netbeans.org/main/rev/ecd5548f1223

This trick violates some swing rules:
do not access models out of EDT, 
do not firePropertyChange out of EDT

This is a way for races and deadlocks. 
Please fix the problem not in debugger core (by violating swing rules), 
but in jdpa part where lock was taken for too long time.

P1, because this issue prevents DBX integration into 6.8 (originally worked fine in 6.5)

FYI, assert in CommonDbx.java 1103 is:
assert SwingUtilities.isEventDispatchThread();
Comment 2 Martin Entlicher 2009-09-16 19:48:56 UTC
Well viewmodel is not Swing and we were facing big issues when all methods on models were called in AWT.
But I understand that there are valid use-cases for calling models in AWT.
For some time already I have an idea how clients could specify whether they need the synchronous or asynchronous model.
I've already started to work on this, but it was abandoned later due to other priorities. Perhaps it's time to resurrect
this idea now.

getValue() is already called in an RP, therefore calling setValue() in RP as well seems to be the natural fix of the
issue #158219, at least for consistency reasons.

Since debuggers build on top of JDI need asynchronous behavior, it would be an overkill to force every model
implementation to deal with threading and correct lazy behavior. Thus my conclusion is that we need to support both
approaches.
Comment 3 Martin Entlicher 2009-09-17 15:46:21 UTC
Please let me know what would you think about following API and whether it would solve this (and possibly other) problem
with threading of viewmodel:

Introduce a new AsynchronousModel interface, which would be registered along with other models like TreeModel, NodeModel
and TableModel:

public interface AsynchronousModel extends Model {

    static enum CALL { DISPLAY_NAME, SHORT_DESCRIPTION, VALUE, CHILDREN }

    ThreadProvider asynchronous(CALL asynchCall, Object node);

    public static final class ThreadProvider extends Object {

        public static final ThreadProvider CURRENT = new ThreadProvider(null);

        private final RequestProcessor rp; // RP or null for AWT

        public ThreadProvider(RequestProcessor rp) { this.rp = rp; }

        public boolean isCurrent() { return rp == null; }

        public RequestProcessor getRequestProcessor() { return rp; }
    }
}

The idea is, that asynchronous() method provides hint to viewmodel in which thread it should call methods identified by
CALL enum.
DISPLAY_NAME is for NodeModel.getDisplayName(), ExtendedNodeModel.setName()
SHORT_DESCRIPTION for NodeModel.getShortDescription()
VALUE for TableModel.getValueAt() and TableModel.setValueAt()
CHILDREN for TreeModel.getChildrenCount() and TreeModel.getChildren()

The rest of the methods would be called synchronously (as they are now), or additional enums can be added.
ThreadProvider.CURRENT can be returned for synchronous calls and new ThreadProvider(RequestProcessor) for asynchronous
calls in RP.

If this is feasible solution for you, I'll prepare the API change. Any hints/suggestions are welcomed.
Comment 4 Vladimir Voskresensky 2009-09-18 14:48:48 UTC
Hi, 
In general (as soon as NB is based on Swing) I think for users of API/SPI it's easier to think in already known concepts
instead of learning new one. That's why in Swing you don't have each class marked with it's threading model, it is done
on top swing level and only exceptions are marked :-)

Introducing proposed threading model will definitely help. Just make sure that "default" models are swing-rule based :-)
Comment 5 Martin Entlicher 2009-09-18 15:25:51 UTC
Swing is one thing and NetBeans another. NetBeans certainly can not run everything in AWT like Swing does, since it uses
other technologies as well (like compiler and JDI for instance). NetBeans just uses Swing as it uses other packages.

The proposed API is similar to
http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/actions/CallableSystemAction.html#asynchronous()
therefore it's not a new concept. It's different from this in allowing to return ThreadProvider instead of true/false,
which provides better flexibility and extensibility for the future.

I'm really reluctant to make the synchronous model as the default. This would be an incompatible change. And do such
change after feature freeze is not a good idea. This is the same problem as CallableSystemAction.asynchronous() was
solving, where they decided to keep the compatibility and have the asynchronous model as the default one.
Comment 6 Vladimir Voskresensky 2009-09-18 15:35:06 UTC
Ok. I got your points and that's fine.
Btw, what about introducing in ThreadProvider  
public static final ThreadProvider DEFAULT = new ThreadProvider(new RequestProcessor("Default", 1));
it will be default dispatcher  (just not to create a lot of new RPs by clients)?
Comment 7 Martin Entlicher 2009-09-18 15:47:06 UTC
Creating a lot of new RPs should not be a problem, since the threads are shared among all RPs. But this good suggestion
anyway, it improves the usability of the APIs.
Thus, O.K., I'm going to submit a separate issue for the API review...
Comment 8 Vladimir Voskresensky 2009-09-21 09:37:04 UTC
Martin, what about the similar issue [1]. Would it be fixed by proposed API change or another one is needed as well?
Thanks,
Vladimir.
[1] breakpoint enabling and disabling. 

java.lang.AssertionError
    at com.sun.tools.debugger.dbxgui.debugger.dbx.CommonDbx.sendCommandHelp(CommonDbx.java:1101)
    at com.sun.tools.debugger.dbxgui.debugger.dbx.Dbx.sendCommandHelp(Dbx.java:251)
    at com.sun.tools.debugger.dbxgui.debugger.dbx.Dbx$1.run(Dbx.java:338)
    at com.sun.tools.debugger.dbxgui.debugger.dbx.Dbx.runCommandInt(Dbx.java:297)
    at com.sun.tools.debugger.dbxgui.debugger.dbx.Dbx.sendCommandInt(Dbx.java:336)
    at com.sun.tools.debugger.dbxgui.debugger.dbx.DbxDebuggerImpl.setHandlerEnabled(DbxDebuggerImpl.java:2724)
    at com.sun.tools.debugger.dbxgui.debugger.breakpoints.Handler.postEnable(Handler.java:156)
    at com.sun.tools.debugger.dbxgui.debugger.breakpoints.NativeBreakpoint.setPropEnabled(NativeBreakpoint.java:2291)
    at com.sun.tools.debugger.dbxgui.debugger.breakpoints.NativeBreakpoint.disable(NativeBreakpoint.java:275)
    at org.netbeans.modules.debugger.ui.models.BreakpointsNodeModel$BreakpointEnabler.run(BreakpointsNodeModel.java:223)
    at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:602)
    at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:1070)

Comment 9 Martin Entlicher 2009-09-21 16:37:37 UTC
FYI: I've submitted API change - issue #172694.

Regarding [1] breakpoint enabling and disabling:
This is a different issue. Change of the breakpoint state is implemented asynchronously in BreakpointsNodeModel because
of JPDA debugger. I'll try to move it into JPDA debugger, do you have a separate issue for this?
Comment 10 Vladimir Voskresensky 2009-09-21 17:03:59 UTC
VV1: thanks for issue #172694.

VV2: I've filed issue #172702
Comment 11 Vladimir Voskresensky 2009-09-23 14:36:21 UTC
no reason to delay beta, because of this
Comment 12 Martin Entlicher 2009-09-25 15:15:46 UTC
After API change #172694 was implemented, this needs to be fixed in dbxgui debugger?
Where should we move this? Is there a component for dbxgui debugger around?
Comment 13 Vladimir Voskresensky 2009-09-25 15:27:00 UTC
we will do the rest.
Thanks, Martin!
Comment 14 Vladimir Voskresensky 2009-09-29 12:39:22 UTC
to redirect API calls into the needed thread I have added AsynchronousModelFilter for WatchesView and LocalsView
for now let's use synchronious model (in EDT)

TODO: NativeDebugger or ((Variable)node) should be responsible for providing Threading Model,
because different engines could use different threading models

http://lessing.sfbay.sun.com/hg/toolshg/rev/e5f29d0b673c
Comment 15 ivan 2009-09-29 20:36:56 UTC
We should apply AsynchronousModelFilter to all our models, not just Locals/Watches.
For example, right now bpt enables and disables also run into this problem.

Can you also explain what your TODO means. AFAIK the models are already part
of the "engine", the engine being the whole module as opposed to one class.
Comment 16 Vladimir Voskresensky 2009-09-30 11:19:56 UTC
>We should apply AsynchronousModelFilter to all our models, not just Locals/Watches.
VV1: If there is a reason, let's apply

>For example, right now bpt enables and disables also run into this problem.
VV2: enablement of breakpoints is not covered by filters. 
It was reverted globally to be "swing rules based". See fixed P1 issue #172702

>Can you also explain what your TODO means. AFAIK the models are already part
>of the "engine", the engine being the whole module as opposed to one class.
VV3: Up to discussion. I.e. if we plan to use VariableModel in the common-debugger => for me it looks not very flexible
to hardcode TM (thread model) behavior in it. TM should be delegated to engine specific elements (i.e. impl of Variable
like DbxVariable) or to other... 
Otherwise, of course, it can be overriden if engine likes to provide smth like DbxLocalModel.
Comment 17 ivan 2009-09-30 21:28:09 UTC
VV1: All model setters will eventually find their way to the same assertion in
CommonDbx.sendCommandHelp(). For example: changing counts, conditions etc via the 
outline view table cells.

VV2: OK.

VV3: Will async pulls even work for any of our native debuggers? 
what happens when the debugger is unresponsive after a resumption?
Comment 18 ivan 2009-09-30 23:57:20 UTC
I pulled this change and we updated netbeans.
But something's not right ... in dbxtool only.
The stack view is perpetually showing Please Wait.
Same for Breakpoint view, Variables ...

The IDE seems to be fine.
Comment 19 ivan 2009-10-01 03:44:21 UTC
I thought this should be easy enough for me to fix myself ... just
add some mappings to _dbxtools_ layer files.
But something is weird. Only Locals and Variables were changed for
the IDE yet it's stack, threads etc that is failing.
Comment 20 Vladimir Voskresensky 2009-10-01 20:28:46 UTC
Ivan, please, do not play with the status of issue. We do not have dbx in nb and "RESOLVED/LATER" has a special meaning
Comment 21 Vladimir Voskresensky 2009-10-01 20:48:03 UTC
Ivan, sorry. Let's try to not mark issue as fixed, but use NO68 instead
Comment 22 Vladimir Voskresensky 2009-10-05 13:34:30 UTC
move dbx related issues into dbx-gui component
Comment 23 ivan 2009-10-30 22:56:19 UTC
This "bug" has a common cause and symptoms with any attempt to change values from
any other views since they all go through the same dbxgui code and will cause the same assertion.
For example, any breakpoint property being changed directly in the view will run afoul of this.
So will comprehensively review all pathways using setValueAt().
Comment 24 ivan 2009-10-31 01:53:12 UTC
changeset   : 195:c3374541c7af

        Checked all other "set"s that we may be using:
                ExtendedNodeModelFilter.setName.                not used
                TableModelFilter.setValueAt                     RP
                CheckNodeModelFilter.setSelected                EDT
                TreeExpansionModel.nodeCollapsed/nodeExpanded   EDT
        So only TableModelFilter.setValueAt() is of concern.

        These are defined for:
                WatchModel
                VariableModel
                BreakpointFilter
        WatchModel and VariableModel are already taken care of.

        Fixed BreakpointFilter by adding an implementation for
        AsynchronousModelFilter as for VariableModel and
        registering in layers.

        Now I can verify how well the CountLimit comboBox works.
        It works (almost) fine so closing the very old issue # 76522.