LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How do I create a fault-tolerant DLL call from LV?

I've created an .exe from a VI that calls a DLL, when that DLL crashes, it crashes the whole application.  This DLL is too complicated to completely debug and it, in turn calls DLLs I have no control over.  It crashes approximately once every 100,000 iterations.

How do I make a DLL call fault-tolerent?
0 Kudos
Message 1 of 4
(2,791 Views)
There are a couple of paths you can go down here...
 
If you believe that the DLL is not really doing anything bad with memory or such, but is doing something like a divide by zero and throwing an exception (just an example), you can put a try/catch block inside the DLL entry point. How to do this depends on whether you are in Linux, Windows or Mac and whether you are using C++ or some other language. But basically, if the exception doesn't make it up to LV, then the call won't generate the popup.
 
*WARNING* This is a big assumption. The DLL is in the same process as LabVIEW - the DLL is perfectly capable of corrupting the memory of LabVIEW itself if it has a misplaced pointer. That in turn could cause almost anything to happen. This is why the popup requires you to restart LV.
 
If you can't say that with confidence, then the only option is to have the DLL hosted in another application that you can restart from LabVIEW. For example, if you are on Windows, you could create a COM wrapper for the DLL and have it hosted by the DllHost.exe program. If not, or you don't want to do COM, then you need to write a program that communicates with the main LV app and makes the call. This can all be done within LabVIEW code, but it isn't simple. It also isn't fast.
 
 
0 Kudos
Message 2 of 4
(2,783 Views)
I had tried the first option with fault traps on any/all signals related to math errors with no good results.

I was hoping you'd say NI has a new fault-resistant "Call Library Function Node" with an "error" output wire.  Or that there was a trick like setting up as re-entrant code which would set up a new, separate memory space every time I called the DLL.  Or that I should use WINAPI "stdcall" instead of "C".

I came to the realization that I may need a separate executable listening on a TCP/IP socket for data to process, if the call timed out, then I could start a new process.  I guess I just wanted some consensus.  I think NI should fix this in LabView -- it'll be more efficient.

BTW:  If I knew we should use COMs do do everything useful in LabView, I'd have never learned LV and concentrated on C++.

Thanks for the help,

   ...Dan
0 Kudos
Message 3 of 4
(2,778 Views)
I might not have been very clear in my answer - this isn't a feature that CAN be added to LabVIEW...the DLL threw an unhandled exception across a DLL interface - which pretty much means a system exception (code shouldn't be throwing language exceptions across DLL boundaries as they are language specific). This means that something went very wrong with the code and there is a good chance that the process space has been corrupted. And from my own debugging experience, if it's only crashing 1 time out of 100,000, that doesn't mean it isn't corrupting memory or otherwise causing problems...it was just the time it was caught.
 
Considering this, the Call Library Node already is fault tolerant - we catch the exception and report it to the user. You have a valid position that we should simply return this as an error. It's also a valid position that it would be a road paved with good intentions. All you need to do is remember what life was like in Windows 3.1 - where one process could silently corrupt another - to realize the amount of untraceable errors that could occur. Yes, the error out value should be handled by the user, but when an application of 100's or 1000's of VIs crashes seemingly at random because someone didn't, you can see the problem.
 
I will say I like the idea of a separate memory space. It is unfortunate that Windows only offers that through creating a separate process, but it is a neat idea. I worked in the VXI/VME world for a while, which does have multiple address spaces.
 
BTW - using signal handlers to catch exceptions is unfortunately not a 100% solution...signals are a partial port of a Unix concept in Windows. You would be best to use SEH around the call (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/key_s-z_4.asp). If the DLL is already a C++ DLL, then you can use the global catch of C++ instead
 
int err = 0;
try {
...
} catch(...) {
   err = -1;
}
 
Again, you still are at risk of a corrupted process, but this allows you to avoid our handling of it.
 
Having spent years writing and (god help me) debugging device drivers, I love this topic. If you want to talk more about it and various options, feel free to shoot me an email at bloggingbrian@gmail.com.
0 Kudos
Message 4 of 4
(2,767 Views)