From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Desktop Execution Trace Toolkit finding "fake" reference leak with SubPanels?

I'm currently using the Desktop Execution Trace Toolkit (DETT) to track down reference leaks in my application. One of the operations that my application performs frequently is switching between different VIs in a SubPanel, depending on the type of data that it is displaying. The DETT is reporting that there is a reference leak with my SubPanel switching.

 

A minimal example that demonstrates how references are being opened is shown below:

 

image.png

image.png

 

As you can see, it looks like a new refnum to the VI that is inserted into the SubPanel is created when you read the "Inserted VI" property of the SubPanel. This will return the same refnum if you read it multiple times, however removing and re-inserting the VI will cause a new refnum to be created. Indeed, running the DETT on this code finds that there are two reference leaks in this operation (and I have confirmed that these are both due to the references that are created by reading the "Inserted VI" property):

 

image.png

 

Now the weird thing is, if I try to query any properties of the original "Inserted VI" refnum after i have removed the VI, I get an error saying that the VI refnum is invalid, suggesting that the "Remove VI" operation actually closes the reference that was opened when reading the "Inserted VI" property:

 

image.png

 

image.png

 

This suggests to me that these references are being closed and there isn't actually a reference leak in this code after all.

 

Can anyone confirm whether or not the "Remove VI" operation closes the references that are opened by reading the "Inserted VI" property, and if so, is there a way that I can report this as a bug in the DETT?

Message 1 of 8
(2,682 Views)

Following up with one more bit of information.

 

If I close the reference created by the "Inserted VI" property read, the DETT no longer detects a leak for that reference, even though the Close Reference function will generate an error. Therefore, if I modify my example above to close the first of the two "leaked" references (and clear the resulting error) then the DETT will only find one reference leak instead of two:

 

image.png

 

0 Kudos
Message 2 of 8
(2,628 Views)

I should also perhaps mention that I am using LabVIEW 2016 f5 64-bit running on Windows 10 and the most recent version of the DETT:

 

image.png

0 Kudos
Message 3 of 8
(2,624 Views)

You did not expect a quick and easy response to this query I hope...

 

Try changing over to an "Invoke Node >>> Run VI" method so that you have access the "Auto Dispose Ref" option and try your code with both true and false.

 

Some questions that go with that experiment;

 

Is the target VI actually running?

If it is not running and you add a while loop to keep it running how do things change?

 

Aside from that I suspect the new ref is being generated by the "Insert" and not the "InsertedVI" since reading it twice returns the same number.

 

Let us know what you find please!

 

Ben

 

 

 

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 4 of 8
(2,617 Views)

This is in LabVIEW 2018, your mileage may vary.

 

Following your diagram, I can replicate the reference leak with DETT.

 

However, in my case, I can get RID of the reference leak AND have no error, if I change the order of operations. See below. Try it with with your system.

 

mcduff

 

Snap4.png

Message 5 of 8
(2,602 Views)

Thank you for the replies!

 


@Ben wrote:

You did not expect a quick and easy response to this query I hope...


A man can dream can he not? Smiley Tongue

 


@Ben wrote:

Try changing over to an "Invoke Node >>> Run VI" method so that you have access the "Auto Dispose Ref" option and try your code with both true and false.


It looks like this implementation produces the same 2 reference leaks in the DETT with the "Auto Dispose Ref" option set to both T and F:

 

image.png

 

Further, there are also some other limitations to this implementation that would prove to be issues in the context of how I'm running/managing the SubPanel VIs in my full application:

  1. I cannot set the x80 (prepare to call and forget) flag when opening the VI reference.
  2. The VI reference cannot be strictly typed, meaning I can't pass in values to the front-panel controls that are connected to the connector pane of the VI when I run it.

 


@Ben wrote:

Is the target VI actually running?

If it is not running and you add a while loop to keep it running how do things change?


Yes, the "subpanel.vi" that I am inserting into the SubPanel in this test looks like this:

 

image.png

 

In my full application, all of the VIs that I am switching in/out of the SubPanel are definitely running at the time.

 


@mcduff wrote:

However, in my case, I can get RID of the reference leak AND have no error, if I change the order of operations. See below. Try it with with your system.

 

Snap4.png


Hmm, this didn't work for me. I wonder if perhaps the reason this doesn't produce a reference leak in the DETT is that the output of the "Inserted VI" property isn't wired to anything, so the LabVIEW compiler is optimizing the code by removing it altogether? Indeed, if I simply delete the wires going into the type cast functions in my original example (with everything else unchanged) then I also see the reference leaks disappear from the DETT.

 

I should also mention that closing the reference after running the VI wouldn't work for my full application because I need to keep references to all of my "SubPanel VIs" around in order to be able to swap out which one is displayed in the SubPanel. The VIs are all running in the background and the top-level VI inserts/removes them into the SubPanel depending on what type of data it needs to display at the time, so it needs to hold onto the references to the VIs. These references are all closed when the top-level VI exits.

0 Kudos
Message 6 of 8
(2,573 Views)

@EthanJ wrote:

...

Further, there are also some other limitations to this implementation that would prove to be issues in the context of how I'm running/managing the SubPanel VIs in my full application:

  1. I cannot set the x80 (prepare to call and forget) flag when opening the VI reference.
  2. The VI reference cannot be strictly typed, meaning I can't pass in values to the front-panel controls that are connected to the connector pane of the VI when I run it.

...


You can still open the ref the same way as your original code.

"Invoke Node >>> Set Control Value" is how we had to do it before that node was invented.

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 7 of 8
(2,561 Views)

@EthanJ wrote:

  1. I cannot set the x80 (prepare to call and forget) flag when opening the VI reference.
  2. The VI reference cannot be strictly typed, meaning I can't pass in values to the front-panel controls that are connected to the connector pane of the VI when I run it.

 

In my full application, all of the VIs that I am switching in/out of the SubPanel are definitely running at the time.



I should also mention that closing the reference after running the VI wouldn't work for my full application because I need to keep references to all of my "SubPanel VIs" around in order to be able to swap out which one is displayed in the SubPanel. The VIs are all running in the background and the top-level VI inserts/removes them into the SubPanel depending on what type of data it needs to display at the time, so it needs to hold onto the references to the VIs. These references are all closed when the top-level VI exits.


This is a bit different than you posted in Message #1, where you had the x80 flag and an async call.

 

I just tested a program that I am working on. It has a subpanel and it has a subVI that is always running that is sometimes inserted, taken out of the subpanel depending on user interaction. This subVI runs until the Main program is stopped, that is, it is continuously running whether it is inserted, taken out, etc of the subpanel. I just tested with DETT and do not have a reference leak. This is what I do, in a state machine:

 

  1. Close any VI reference that is in the subpanel. (Ignore any error 1026, this handles the case if nothing in the subpanel.)
  2. Method -> Remove VI from subpanel, no error if nothing there.
  3. Use a Static VI reference, not strictly typed, for the subVI I want to insert.
  4. Use the Insert VI method.

Since it is already running, no need to do anything else, like Run VI method, etc.

 

In the same subpanel I may insert a subVI that only runs while in the subpanel, then in addition to the first 3 aforementioned steps I do:

  1. Set a Control value for the subVI, in my case a user event reference.
  2. Use the RunVI method.
  3. Use the insert VI method.

mcduff

 

PS Note the VIs I am inserting are state machines, that start and exit execution states.

Message 8 of 8
(2,541 Views)