04-21-2011 05:35 AM
We finally found at least the exact circumstances that create the problem and are investigating the underlying cause with the driver vendor: We had a sequence which did the following:
In Setup:
close_all_framegrabbers() // just for convenience and safety:-)
open_framegrabber(...a particular one)
In Main it waited in a while loop for commands over a queue and did:
the idea being that we reset the frame grabbers in case of an error and start with a clean initialization. Now after the second close/open sequence, Main returned to the condition of the while loop and that is the point where the 17501 error struck.
It turned out that we did NOT have the -17501 error if we left out the first close_all_framegrabbers() OR if we opened one before so that the call did not work on an empty list. We are now investigating with the driver vendor what calls are made by close_all_framegrabbers() in such a case which might lead to this behavior. I will post if we learn anything in this respect in case it may help others finding / fixing such errors.
Regards
Peter
04-21-2011 10:07 AM
Interesting. Thanks for letting us know.
-Doug
04-29-2011 02:58 AM
I have some more information. First the full wording of the error message:
Error message: -17501: Error executing 'Select' step. Error in step 'Case' at index 18 in step group Main of sequence 'MainSequence'. Wrong parameter. One reason this can occur is if the interface of your COM server cannot be marshaled. This can happen if your server is not using the default OLE marshaling implementation and does not implement its own proxy and stub code. If you write your server using Visual C++ you can add the oleautomation attribute to your interface in order to use the default OLE marshaling implementation. Alternatively, COM does not require marshaling if the server's threading model is the same as the client thread's apartment. You can try changing your server's threading model or the client thread's apartment to avoid the need to marshal the interface. Error accessing item 'EvaluatedItemExpr'.
It is always a conditional, sometimes if, sometimes while, here a case where the error happens. We now had this error even when closing a correctly initialized resource and we noticed that immediately after the close_framegrabber command, we had the following message in DbgView:
00000777 17:00:59.250 [2008] WARNING!!! 'Error: ~TSGlobalInterfacePointer returning unknown %s.
00000778 17:00:59.250 [2008] ' Line 113 in function in file .\GlobalInterfacePointer.cpp
00000779 17:00:59.250 [2008] Compilation Date: Apr 23 2008 Compilation Time: 14:02:49
After a few of those, the 17501 error occurs fairly reliably.
Can you derive any hint from this what the close_framegrabber function possibly does to cause this?
Best regards
Peter
04-29-2011 06:01 AM
I forgot to mention that this is a driver for plug and play cameras; therefore the driver creates a hidden window to have a message loop to catch plug and play messages. The driver manufacturer says that this is the reason why the camera must be closed from the same thread in which it was initialized (which we do).
Perhaps that gives additional hints as to the root of the problem.
Regards
Peter
04-29-2011 10:04 AM
Is this driver a COM server?
When teststand releases a COM reference it gives it to a worker thread to do the release, thus the release of the COM object is not happening in the same thread (The warning you are seeing is an error that is occurring during the cleanup of a COM reference). For a well-behaved COM server this should not be a problem. A COM server that requires all calls into it to be from the same thread should be implemented as a single-threaded apartment server. That way, no matter which thread does the release on the client side, the actual call into the server will be done by the original thread that created it (this is handled internally in the OS by COM - it basically marshals the call to the original thread).
That said, it's possible they did not implement their server as a single-threaded apartment server and instead implemented it as a multi-threaded apartment server. If so, their additional requirement that the reference be released in the same thread that created it is beyond the normal requirements of a COM server.
You can workaround this non-standard requirement by writing a code module to do the final release on their object rather than it being TestStand. One way to do this would be to pass the COM reference into a code module which then stores it in a global variable. Then in a statement step set all of your object reference variables which refer to their objects to "Nothing". Then in another call into the code module tell it to release the reference it has stored.
Since I don't really know if the driver is a COM server, it's possible none of this applies and we are on the wrong track.
-Doug
05-13-2011 07:53 AM
Hi,
we are still trying to clarify this with the driver manufacturer and I have a question concerning the COM reference issue.
We are opening the frame grabber in a script procedure which itself is interpreted by a DLL containing the script engine. None of these, as far as we know, has any relation to COM. The only common element I currently see is the similarity between the driver and an STA COM server with respect to the message loop in the hidden window.
So my question is: Does TestStand execute the code where the warning that we see comes from only if it "knows" that there is a COM reference to be released (i.e. the COM reference has been created in a TestStand step so that TestStand knows this variable to be a COM reference) or are there other circumstances where that might happen?
Regards
Peter
05-16-2011 09:39 AM - edited 05-16-2011 09:42 AM
That warning should only occur for COM objects that are stored in TestStand Object Reference variables. It would happen when that variable is being destroyed or set to another value. You will not get that warning for COM objects that TestStand knows nothing about.
The warning/freeing can happen somewhat asynchronously from the code that caused the Object Reference variable to be destroyed or cleared for two reasons, 1) because of .NET garbage collection if a reference to the object reference variable is ever stored in .NET, and 2) because teststand releases COM references semi-asynchronously to avoid deadlocks (it does wait for all of them to be freed between each step though).
It's possible these errors might happen as a side effect of another problem, if, for example, something like memory corruption is occurring.
Another potential cause could be if code in a user's code module uninitializes COM out from underneath one of our threads. All TestStand threads are already initialized for COM.
Hope this helps,
-Doug
11-22-2011 03:13 AM
Hi,
I experience the same error and what raises my attention is when you say that it is always conditional.
To summazize, my application tests in bach mode 72 products in parallel.
At the beginning in order to limit stack operations, I programmed my sequence avoiding sequence calls, while loops and conditional structures (I used goto statements and 1 subsequence).
Then I upgraded my machine: architeture 64 bits many RAM. I have to make an evolution but mainly, I do the same things. But changed my sequence to improve lisibility and I use sequence calls, while loops and if conditions.
And this error occurs.
Défaillance irrémédiable.
One reason this can occur is if the interface of your COM server cannot be marshaled. This can happen if your server
is not using the default OLE marshaling implementation and does not implement its own proxy and stub code. If you
write your server using Visual C++ you can add the oleautomation attribute to your interface in order to use the
default OLE marshaling implementation. Alternatively, COM does not require marshaling if the server's threading model
is the same as the client thread's apartment. You can try changing your server's threading model or the client
thread's apartment to avoid the need to marshal the interface.
Error code:-17501, Unexpected Operating System Error
Source 'TSAPI'
I inclined to think it is linked because it is the main change in my program.
For information I've no camera in my application (only Can COM, DMM and Matrix management)
I'm really interested in any information raound this issue.
Thanks, regards.
LL
11-22-2011 10:01 AM
Is it always happening on the same step? What object reference variables are involved? Always the same ones?
-Doug
12-16-2011 07:24 AM
Hello,
hadn't seen the error in some time, but here is a new piece of information.
We had a fairly simple sequence, no multithreading involved at all. It worked without problems, until we did the DCOM settings required for TestStand remote execution on the computer.
At that point, we did not actually do remote execution or inter-computer communication (with queues, notifications etc.). We had the same straightforward sequence, initializing camera, doing a loop for some image capturings, then de-initializing. And at some conditional in between we got a -17501 error which had not occurred before we made the DCOM settings.
I am still fairly in the dark here, I must admit. But perhaps someone can do something with this information.
Regards
Peter