Jump to content

more breakpoint weirdness


Recommended Posts

Every time I encounter something like this, my first thought is, "What am I doing wrong?"

Is this one of those known behaviors that everyone but me knows about? See screenshot. How is it possible to update an indicator if the upstream wire has a breakpoint that hasn't paused execution?

127681872_breakpointweirdness.png.05af22ac49b91886e919b038279abe3c.png

 

Link to comment

I have never really trusted breakpoints on wires like this, especially going to indicators. I prefer structures/primitives/VIs. I suspect if the breakpoint was on the outside of the top while loop it would break correctly.

Still seems like a bug though.

Link to comment

I would guess it is a compiler optimization, where the terminal points to the same memory location as the output tunnel.  It is arguable that some breakpoint weirdness is better than the forced memory copies just in case a breakpoint might be added at some point (given the huge number of places a breakpoint could be added).  

Alternately, it could be something to do with "chunking"; dividing a VI into executable chunks.  I wouldn't be surprised if a breakpoint can only pause between chunks.  Exiting the loop and writing to the indicator terminal could be one chunk.

Link to comment

As drjdpowell mentions the bug could be caused by optimizations, but it should still be considered a bug that optimizations are allowed to interfere with the data flow in debugging mode. I suggest you post it on the ni.com forum as well and see what NI says.

Link to comment

  

1 hour ago, drjdpowell said:

How much of a performance loss would you be prepared to take to fix this bug?

In the few cases where performance is that critical you will probably have to get by without traditional debugging anyhow. 

Do you expect you comfy car seat to occasionally disappear, and accept that as a consequence of wanting a quick car...? Sure, in the rare cases you need it for drag racing 😄 I do not consider key features like data flow and breakpoints something that should be allowed to occasionally break/act randomly. Either you have them and they work as they should, or you remove/disable them and explain/visualize why they are sacrificed (to get performance) until you are able to offer both performance and proper behavior. Disabling debugging and/or turning down/off optimizations could still be an option in the few cases where that is the only way to get the necessary performance. 

Edited by Mads
Link to comment

If it were an optimization then we should be prevented from placing breakpoints where they won't function as expected. I know breakpoints have been buggy for a long time. The fact that in 2015 I could remove the wait functions and get the execution to pause as soon as I ran the VI tells me that at least some of the quirks have been fixed over time.

 

The fix is to place a sequence structure between the breakpoint and indicator.

1321805824_breakpointweirdnessfix.png.2e1b303351b68e6eab5bbe3aa9a89afc.png

Link to comment

I know there was a discussion on the NI forum about execution highlighting with a similar issue. A VI "later" on the error wire was shown to be executed before a VI "earlier" on the wire. In reality, that probably didn't happen, but I guess the reason can be the same (probably something like what drjdpowell is saying). But, I know that it was answered in detail from someone from NI. Unfortunately I cannot for my life find the thread. I think it was some tcp/ip VIs or perhaps a save to text file involved.

Link to comment

Disclaimer: The following is based on my own observations and experience, so take it with a grain of salt!

15 hours ago, G-CODE said:

How is it possible to update an indicator if the upstream wire has a breakpoint that hasn't paused execution?

The user interface does not follow the dataflow model. It runs in its own thread and grabs new data as it becomes available. In fact, the UI update rate is much slower than the actual execution speed of the VI -->VI Execution Speed - LabVIEW 2018 Help - National Instruments (ni.com). The location of the indicator on the block diagram simply defines which data is used, not necessarily when the data is being displayed. In your example, the numeric indicator uses the data from the output terminal of the upper while loop, but it does not have to wait for the wire to pass the data. Instead it grabs the data when it is available. Because of that you can't rely on the front panel to tell dataflow.

Execution Highlighting is also misleading because it isn't based on VI execution, but rather on a simulation of the VI executing (it's a approximation at best). LabVIEW simply displays the dot and postpones UI updates until the dot reaches the next node. Not to forget that it also forces sequential execution. It probably isn't even aware of the execution system, which is why it will display the dot on wires that (during normal execution) wouldn't have passed any data yet.

Breakpoints, however, are connected to the execution system, which is why they behave "strangely". In dataflow, data only gets passed to the next node when the current node has finished. The same is true for diagrams! The other thing about breakpoints to keep in mind is that "execution pauses after data passes through the wire" --> Managing Breakpoints - LabVIEW 2018 Help - National Instruments (ni.com)

In your example, data passes on the wire after the block diagram is finished. Here is another example that illustrates the behavior (breakpoint is hit when the block diagram and all its subdiagrams are finished):

image.png.909971d0c51b37eab96f2d02bdeb9712.png

Now think about indicators and controls as terminals from one block diagram (node) to another.

image.png.3728aa3ec95290754ab3b4d1d0e2bc00.png

According to the dataflow model, the left diagram (Block Diagram A) only passes data to the right diagram (Block Diagram B) after it is complete. And since the breakpoint only triggers after data has passed, it needs to wait for the entire block diagram to finish. Whether or not the indicator is connected to any terminal makes no difference.

This is also not limited to indicators, but any data that is passed from one diagram to another:

image.png.3c626e7179aa0a7cd00f52a376217da0.png

Hope that makes sense 😅

 

Edited by LogMAN
Link to comment
Quote

The user interface does not follow the dataflow model.

I think it's really helpful to point that out.

 

Quote

Now think about indicators and controls as terminals from one block diagram (node) to another.

Whether or not the indicator is connected to any terminal makes no difference.

Thinking about this.... I can't figure out if now we are trying to explain why it's expected behavior or if we are trying to justify unexpected behavior (or something in between). 🙂

Link to comment
2 hours ago, LogMAN said:

he user interface does not follow the dataflow model. It runs in its own thread and grabs new data as it becomes available. In fact, the UI update rate is much slower than the actual execution speed of the VI -->VI Execution Speed - LabVIEW 2018 Help - National Instruments (ni.com). The location of the indicator on the block diagram simply defines which data is used, not necessarily when the data is being displayed. In your example, the numeric indicator uses the data from the output terminal of the upper while loop, but it does not have to wait for the wire to pass the data. Instead it grabs the data when it is available. Because of that you can't rely on the front panel to tell dataflow.

I think this is about as wrong as it can get.  If an indicator is wired only (no local variables or property nodes breaking the data flow) it shall abide the rules of data flow. The fact that the UI is not synchronously updated (it can be set to be, but it is not here) can explain that what you see in an indicator is not necessarily its true value  (the execution, if running fast, will be ahead of the UI update)- but it will never be a *future* value(!). As for breakpoints they do not exist just in the UI - they are supposed to act at the code level, and their execution should be controlled by data flow. So in the case of a break point the break will (should) occur as soon as it has its incoming data available at the execution level, not the UI. The UI will update the state at its pace, but UI is just displaying the state after it has occured, not deciding when it is entered.

One thing that makes this more complex in LabVIEW and in this example is that we are dealing with parallel execution within the same diagram. A breakpoint should really (we expect it to) as soon as it has its input value cause a diagram-wide break, but it does not. Instead it waits for the parallell code to finish, then breaks. As for the indicator showing the value prior to the break that part is explained by the bit LogMAN refers to; that breakpoints allow the value to pass before they hit the break...

Edited by Mads
Link to comment
9 hours ago, LogMAN said:

The user interface does not follow the dataflow model.

9 hours ago, G-CODE said:

I think it's really helpful to point that out.

7 hours ago, Mads said:

I think this is about as wrong as it can get.

Please keep in mind that it is only my mental image and not based on any facts from NI.

9 hours ago, G-CODE said:

Thinking about this.... I can't figure out if now we are trying to explain why it's expected behavior or if we are trying to justify unexpected behavior (or something in between). 🙂

Perhaps both. If we can understand the current behavior it is easier to explain to NI how to change it in a way that works better for us.

7 hours ago, Mads said:

If an indicator is wired only (no local variables or property nodes breaking the data flow) it shall abide the rules of data flow. The fact that the UI is not synchronously updated (it can be set to be, but it is not here) can explain that what you see in an indicator is not necessarily its true value  (the execution, if running fast, will be ahead of the UI update)- but it will never be a *future* value(!).

Here is an example that illustrates the different behavior when using indicators vs. property nodes. The lower breakpoint gets triggered as soon as the loop exits, as one would expect.  I have tried synchronous display for the indicator and it doesn't affect the outcome. Not sure what to make of it, other than what I have explained above 🤷‍♂️

image.png.99aa2db9f7d548a2f632e0526e8d19de.png

7 hours ago, Mads said:

A breakpoint should really (we expect it to) as soon as it has its input value cause a diagram-wide break, but it does not. Instead it waits for the parallell code to finish, then breaks.

I agree, this is what most users expect from it anyway. It would be interesting to hear the reasoning from NI, maybe there is a technical reason it was done this way.

Link to comment
On 2/24/2021 at 6:19 AM, G-CODE said:

Every time I encounter something like this, my first thought is, "What am I doing wrong?"

Is this one of those known behaviors that everyone but me knows about? See screenshot. How is it possible to update an indicator if the upstream wire has a breakpoint that hasn't paused execution?

You are trying to force your mental model onto LabVIEW data flow. But data flow does not mandate or promise any specific order of execution not strictly defined by data flow itself.

A LabVIEW diagram typically always processes all input terminals (controls) and all constants on the top level diagram (outside any structure) first and then goes to the rest of the diagram. The last thing it does is processing all indicators on the top level diagram. There is no violation of any rule in doing so. Updating front panel controls before the entire VI is finished is only necessary if the according terminal is inside a structure. Clumping the update of all indicators on the top level diagram into one single action at the end of the VI execution does not delay the time the VI is finished but can save some performance. It also has to do with the old rule that it is better to put pass through input and output terminals on the top level diagram and not bury them somewhere inside structures, aside from other facts such as readability and the problem of output indicators potentially not being updated at all for subVIs, retaining some data from previous execution and passing that out.

Edited by Rolf Kalbermatter
Link to comment
1 hour ago, Rolf Kalbermatter said:

The last thing it does is processing all indicators on the top level diagram.

But this isn't the issue is it? The front panel is updated long before the VI finishes executing.

Link to comment
8 hours ago, G-CODE said:

But this isn't the issue is it? The front panel is updated long before the VI finishes executing.

Is it? Then there would be indeed a discrepancy between when the front panel update is executed and when the debug mechanism considers the data to be finally going through the wire. Which could be considered a bug strictly speaking, however one in the fringes of "who cares". I guess working 25+ years in LabVIEW, such minor issues have long ago ceased to even bother me. My motto with such things is usually "get over it and live with it, anything else is bound to give you ulcers and high blood pressure for nothing".

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.