das-developers / das2java

The original das2 library. Provides interactive publication-ready 2-D plotting
https://das2.org
GNU Lesser General Public License v3.0
4 stars 0 forks source link

Stack overflows upon rendering since issue 38 changes #68

Closed DiamondJim87 closed 1 year ago

DiamondJim87 commented 1 year ago

The changes to address issue #38 somehow triggers a stack overflow under some circumstances. This is the commit whose (short) hash is 3f666a, and whose summary is "bugfix https://github.com/das-developers/das2java/issues/38: cadence on Juno/WAV/Survey". If you back up to the commit before that, the problem described here does not occur.

I stopped the code in the debugger after one extra recursion so you could see the interesting part of the stack trace. If I continue running at this point, it continues to repeat the top two lines, i.e., the code continues to ping-pong between the two methods DataSetOps.sliceProperties0(...) and DDataSet.slice(...) until the stack overflows.

DataSetOps.sliceProperties0(int, Map) line: 1152 
DDataSet.slice(int) line: 619   
DataSetOps.sliceProperties0(int, Map) line: 1152 
DDataSet.slice(int) line: 619   
DataSetUtil.gcd(QDataSet, QDataSet) line: 1384  
DataSetUtil.guessCadenceNew(QDataSet, QDataSet) line: 2182  
DataSetUtil.inferBins(QDataSet) line: 1566  
LanlNNRebinner.rebin(QDataSet, RebinDescriptor, RebinDescriptor, RebinDescriptor) line: 127 
SpectrogramRenderer.updatePlotImage(DasAxis, DasAxis, ProgressMonitor) line: 1022   
DasPlot.paintComponent(Graphics) line: 1454 
DasPlot(JComponent).paint(Graphics) line: 1050  
DasCanvas(JComponent).paintChildren(Graphics) line: 883 
DasCanvas(JComponent).paint(Graphics) line: 1059    
DasCanvas(JLayeredPane).paint(Graphics) line: 586   
DasCanvas(JComponent).paintToOffscreen(Graphics, int, int, int, int, int, int) line: 5213   
RepaintManager$PaintManager.paintDoubleBuffered(JComponent, Image, Graphics, int, int, int, int) line: 1579 
RepaintManager$PaintManager.paint(JComponent, JComponent, Graphics, int, int, int, int) line: 1502  
RepaintManager.paint(JComponent, JComponent, Graphics, int, int, int, int) line: 1272   
DasCanvas(JComponent)._paintImmediately(int, int, int, int) line: 5161  
DasCanvas(JComponent).paintImmediately(int, int, int, int) line: 4972   
RepaintManager$4.run() line: 831    
RepaintManager$4.run() line: 814    
AccessController.doPrivileged(PrivilegedAction, AccessControlContext) line: not available [native method]    
ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(PrivilegedAction, AccessControlContext, AccessControlContext) line: 74   
RepaintManager.paintDirtyRegions(Map) line: 814    
RepaintManager.paintDirtyRegions() line: 789    
RepaintManager.prePaintDirtyRegions() line: 738 
RepaintManager.access$1200(RepaintManager) line: 64 
RepaintManager$ProcessingRunnable.run() line: 1732  
InvocationEvent.dispatch() line: 311    
EventQueue.dispatchEventImpl(AWTEvent, Object) line: 758    
EventQueue.access$500(EventQueue, AWTEvent, Object) line: 97    
EventQueue$3.run() line: 709    
EventQueue$3.run() line: 703    
AccessController.doPrivileged(PrivilegedAction, AccessControlContext) line: not available [native method]    
ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(PrivilegedAction, AccessControlContext, AccessControlContext) line: 74   
EventQueue.dispatchEvent(AWTEvent) line: 728    
EventDispatchThread.pumpOneEventForFilters(int) line: 205   
EventDispatchThread.pumpEventsForFilter(int, Conditional, EventFilter) line: 116    
EventDispatchThread.pumpEventsForHierarchy(int, Conditional, Component) line: 105   
EventDispatchThread.pumpEvents(int, Conditional) line: 101  
EventDispatchThread.pumpEvents(Conditional) line: 93    
EventDispatchThread.run() line: 82  

It will (as usual with us) prove difficult to give you simple code that shows the problem. Here are some of the local variables, which might provide a clue:

int index == 1
dep0.back is an array with 202 elements that look OK by eye
dep0 has a properties map containing MONOTONIC=true, FILL_VALUE=-1.0E38, LABEL=Time, UNITS=t2000, NAME=Time, DEPEND_0=Time[Time=202] (t2000)}

I noticed one other oddity I'll mention in case it's relevant. If I run in the debugger but don't set a breakpoint, the debugger halts execution when the stack overflows. Oddly, when this happens, a total of 6 threads seem to hit the same stack overflow. I was surprised that there were multiple threads involved at this point, but maybe that's to be expected.

jbfaden commented 1 year ago

I'm back from vacation and I'll have a look at this today.

jbfaden commented 1 year ago

It's not possible that you have a DEPEND_0 which has a DEPEND_0 property? I'm having trouble generating code which shows the bug. I think that would fail earlier and it looks like I have explicit checks for that condition.

jbfaden commented 1 year ago

Actually I think this Autoplot script shows the same condition:

setScriptDescription('''Try to demo the bug James pointed out.  See 
https://github.com/das-developers/das2java/issues/68''')

ds= ripplesSpectrogramTimeSeries(100)
xt= xtags(ds)
xt.putProperty(QDataSet.DEPEND_0,xt)
ds.putProperty(QDataSet.DEPEND_0,xt)

#plot(0,ds)
ds.slice(52)
plot(1,ds.slice(52))

The commented-out plot command catches the problem, but ds.slice(52) crashes with the same two lines.

I'll put in a check for this condition, it would be an easy mistake to make. Ideally the xt.putProperty(QDataSet.DEPEND_0,xt) call would fail.

jbfaden commented 1 year ago

I put a check in org.das2.qds.AbstractDataSet.putProperty to check if a DEPEND_i is set to the dataset itself. This will issue a warning and return without taking any action.

jbfaden commented 1 year ago

I've put in code which checks to see if DEPEND_i is set to the dataset itself.