LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LabVIEW crashes when reading from MySQL database using NI Database API

Solved!
Go to solution

I'm working on a larger application with plug-in architecture, where some plugins write to DB, some read and outputs, and some read and displays.

LabVIEW 16.0f5 32-bit.  The type of database is 5.5.45 MySQL running locally.

If I'm running multiple "Read" plug-ins the program will crash after a short time (5min - 30min).

 

According to the crash report this happens in "Recordset.llb\\Rec Fetch Recordset Data (R).vi" (see attached).

If there is only one "Read" plug-in running the program will run for days, and maybe never crash.

I will add several Read processes to stress test.

 

I'm getting the impression that the crash happens when two processes reads from the DB at the same time.

Each process opens a connection to the DB. I've been thinking about implementing a locking mechanism, but it's a little complicated to do.

Could this be related to the cursor type? I tried changing it to "static", to see if it made a difference, but it doesn't seem like it mattered.

 

Sounds familiar to anyone? How can I debug this, is it LabVIEW or the database, is it the Database API or my code.

 

Thank you for reading!

0 Kudos
Message 1 of 14
(3,878 Views)

@Oksavik wrote:

I've been thinking about implementing a locking mechanism, but it's a little complicated to do.


Poor man's synchronization: use a VI. If the VI is not reentrant, each run will wait for the VI to stop running. Instant locking mechanism. Not complicated.

 

 

0 Kudos
Message 2 of 14
(3,859 Views)

Hello, and thank you for your reply.

 

As far as I can tell the NI Database API VIs are already not reentrant. However, I'm afraid that the plugins are including some of these VIs through dependencies in their packed libs.

If this is the case I suppose they could be executed simultaneously, even though they are not reentrant.

 

I'm trying the locking mechanism now, however will a semaphore work "across" different packed libs?

0 Kudos
Message 3 of 14
(3,857 Views)

@Oksavik wrote:

I've been thinking about implementing a locking mechanism, but it's a little complicated to do.


Poor man's locking mechanism: use a VI.

 

If the VI is not reentrant, each run will wait for the VI to stop running. Instant locking mechanism. Doesn't need to be complicated (but could be).

 


@Oksavik wrote:

 

Could this be related to the cursor type? I tried changing it to "static", to see if it made a difference, but it doesn't seem like it mattered.


What cursor? What do you mean by 'changing it to "static"'. If you suspect the cursor, disable all code that changes the cursor. Setting it to static could still make it crash.

 

Are you 100% sure you close all connections\references? There could be a limit to how many references (of some kinds) are allowed to be open. If they are not all closed properly, you might run out.

 


@Oksavik wrote:

 

Sounds familiar to anyone? How can I debug this, is it LabVIEW or the database, is it the Database API or my code.


 Desktop Execution Trace Toolkit maybe?

 

Try speeding up certain things to see it crashes occur more often. Or slow down things. Or disable parts.

 

If concurrency problems are suspected, make a test VI that queries the DB, and start it in parallel with some randomness. E.g. try to force crashes.

0 Kudos
Message 4 of 14
(3,856 Views)

Sorry, that post crashed, although it got send anyway...

0 Kudos
Message 5 of 14
(3,853 Views)

About "cursor type". One can select from 4 different cursor types when working with RecordSet in the Database API.

For some reason I had a thought that this might be related to the crash, but it can be completely unrelated.

The default type is "ForwardOnly" which according to the link under is the most limited.

 

http://download.nust.na/pub6/mysql/tech-resources/articles/vb-cursors-and-locks.html

 

References are closed. Also I have had the crash within the first second of running the program, and after 15 minutes. Seems very random.

 

Speeding up Read frequency / adding more Read functions seems to make it crash quicker.

 

I tried running two VIs that query the database continuously at the same time, and I did not get a crash.

0 Kudos
Message 6 of 14
(3,848 Views)

Sounds a bit like you need to isolate exactly what is causing the crash.

A bit clutching at straws as these shouldn't cause crashes but:

Prehaps try updating the ODBC driver?

 

Are you ensuring that the DB references are held in shift registers through any loops?

 

 

Nick
0 Kudos
Message 7 of 14
(3,840 Views)
Solution
Accepted by topic author Oksavik

You need to package your DB code into its own PPL that the other components will use. Otherwise each PPL will load its own copy of the DB code a which is most likely what is causing your crash.

 

While PPLs are a great tool they can complicate your life. Once you start using them you need have to fully commit since if you are using re-use libraries. PPLs will load their own copy of a library or set of VIs. Best case this just means that your application is using more memory. Wort case you get conflict, especially if any of your libraries need to maintain state since you end up with multiple copies. We switched to using PPLs about a year ago and we are now approaching 150 of them to make all of our reuse libraries work properly.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 8 of 14
(3,823 Views)

This was my solution. It required some heavy refactoring, but the result is much cleaner code, and best of all: so far no crashes.

 

My situation was that my DB code (a lvlib built on top of NI Database API) was used in multiple of the PPL.

Each PPL made a copy of the code, which was not made to be run re-entrant. When the PPLs started making calls at the same time it would crash.

 

One of my issues with PPL has been that PPLs that inherit from another PPL would be time consuming to work with.

If I needed to make a change in the parent PPL it meant manually reverting inheritance for all the children.

 

I feared that this would get much worse if I compiled my DB code into a PPL, and replaced the lvlib with lvlibp for all the children PPLs.

I realized that having separate LV-projects for the DB code PPL would be a good idea. So I broke my two projects into four, and now things are much easier.

 

Make changes and build DB code PPL. Import this in "Top plugin"-project, and build Parent plugin PPLs. Import them into "Actual plugins"-project, and build Child plugin PPLs. Import these in Main-project, where I create an .exe file. In the end the application was half the size (18 Mb -> 9 Mb).

 

Hope this might be helpful for someone else later.

 

Thanks Mark_Yedinak.

 

0 Kudos
Message 9 of 14
(3,786 Views)

Are you using "inherit", "parent" and "child" as in OO relations?

 

Or do you mean "inherit->uses", "parent->using", "child->being used"?

 

As in:

"One of my issues with PPL has been that PPLs that inherit from another PPL "

-> "One of my issues with PPL has been that PPLs that is using another PPL "

", and replaced the lvlib with lvlibp for all the children PPLs."

->", and replaced the lvlib with lvlibp for all the PPLs that are used."

etc.

0 Kudos
Message 10 of 14
(3,775 Views)