NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Batch Sequence Shutdown Test Stand Randomly

Hi ,

 

I have a problem with Test Stand in one of my projects .

 

I'm using TS 4 & CVI 9.1 . TS is using CVI DLL .

 

The software is using parallel Device checking for 30 cards , at 25c , 75c and -15c ( temp ).

 

While checking 9-10 evrey thing works fine and well buy in 11 and so on TS crashes randomlly about 1 of 10 times at the crash the is no TS message only Windows not responding message .

 

My main idea was a Resource leaking at the CVI code but i checked it very carefully in addition i cant see the resource trekking in dll mode .

 

Is there any tool , even windows tool or some software i can use to track my memory while working with both programs !? or you have another idea ?

 

Thank you .

 

 

 

-----------------------------------------
Kobi Kalif
Software Engineer

0 Kudos
Message 1 of 8
(4,147 Views)

Hi,

 

unless I think this is not the reason why your TS 4 is crashing.

But it might....

...If you are using the Foreach Step you should visit this thread

http://forums.ni.com/t5/NI-TestStand/TestStand-crashes-by-for-each-loop/m-p/989898#M26030

 

Regards

Juergen 

--Signature--
Sessions NI-Week 2017 2016
Feedback or kudos are welcome
0 Kudos
Message 2 of 8
(4,141 Views)

I'm not using ForEach But I do use select a lot of times , can it be the same effect ?

-----------------------------------------
Kobi Kalif
Software Engineer

0 Kudos
Message 3 of 8
(4,139 Views)

It's quite possible there is a race condition in the code modules in your sequence. You might need to use locks or other synchronization objects to protect critical sections in your code. To debug race conditions I recommend the following:

 

1) Carefully consider any code that uses global variables. Access to variables that are shared between threads must be protected. I'm not referring to just teststand variables, but variables within your code modules as well.

2) Run using a debugger and set the debugger to stop on all Win32 Exceptions. If it hits one, look at what the threads are doing, the memory being accesses is likely being shared between threads and not properly protected. It somewhat depends on what programming languages you are using how best to do this.

 

Hope this helps,

-Doug

0 Kudos
Message 4 of 8
(4,128 Views)

I see since it's my first project using batch sequences I didn't knew that accessing to global parameters needs protection is there a manual that i can read more about using batch / threads and all the needed things to care when do so ? 

 

 

-----------------------------------------
Kobi Kalif
Software Engineer

0 Kudos
Message 5 of 8
(4,122 Views)

I don't think there is a tutorial on multi-threaded programming with TestStand, however I recommend reading the Synchronization Step Types section of the reference manual to familiarize yourself with the synchronization features which TestStand provides and the cases in which they are useful. The issues I mentioned are with multi-threaded programming in general and are not unique to TestStand. TestStand does protect access to TestStand variables when getting or setting values so that your TestStand variables values are kept in a consistent state even when set and get from multiple threads, but if you are making structural changes (i.e. inserting, removing, or renaming properties) to variables shared between threads, access to such variables should be protected with a lock. Also non-TestStand global variables inside of your code modules are not protected at all and you should either avoid using global variables or use a synchronization primitive like a lock or critical section to protect access to shared/global variables.

 

In general, if your sequence doesn't rely on global variables and doesn't need to share data between threads, then multi-threaded programming is pretty straightforward, it's when you are using global variables or sharing data between threads in other ways either unnecessarily or necessarily, that things get more complicated. If you don't really need to share a variable between threads, it's best to use local variables and parameters instead of globals.

 

Hope this helps,

-Doug

0 Kudos
Message 6 of 8
(4,092 Views)

I will do so , but if i can i want to ask something about using global variable..... in general i know using globals with batch mode is probably not a good thing to do.

 

Lets say i have 2 Sequences Main and Sub . in main i have a local var Index i want to update Index From the sequence Sub how can i do that ? ( updating other sequences local vars )

 

I am asking that because i'm using a few globals which i think can cause a lot of problems while working in batch mode .

 

-----------------------------------------
Kobi Kalif
Software Engineer

0 Kudos
Message 7 of 8
(4,071 Views)

There are two possibilities for updating a local in one sequence from a subsequence which that sequence calls.

 

1) Pass the variable as a "By Reference" parameter to the subsequence. Then in the subsequence access it with the lookupstring Parameters.MyParameter. To add a parameter to a sequence, simply insert a variable under the Parameters group. Parameters are passed by reference by default (which is what you want). They can also be passed by value (i.e. a copy to which changes don't affect the original) by changing the setting by right-clicking on the variable and unchecking the by reference setting. Using parameters like this is very flexible and future proof. You can even call the same subsequence from multiple sequences and the subsequence doesn't have to worry about who's calling it. Also it doesn't matter what the name or location of the variable is in the caller, the subsequence just always accesses the variable as its parameter. When you specify the sequence call to call the subsequence you specify what to pass for the parameter.

1a) A variation of this which can help make your code easier to extend is to use a Custom Data Type as the type for your parameter. Make a Custom Data Type that's a container than contains the variables you want to pass. When you need to add a new parameter in the future you can just add it to your Custom Data Type and then you don't have to update any of the places where your subsequences are called to pass the new value. If you go this route I recommend storing the Custom Data Type in a type palette file and keeping it always backwards compatible as much as possible (only add variables, don't remove or change existing variables).

 

2) Another way which is less flexible is that you can use RunState.Caller.Locals.foo to access a local variable in the sequence which is calling the current sequence. This creates an interdependency between the two sequences though which can lead to code maintenance problems because someone could change the calling sequence's variables, not realizing a subsequence depended on the variables they are changing.

 

Hope this helps,

-Doug

0 Kudos
Message 8 of 8
(4,044 Views)