04-20-2011 11:43 AM
Hi there.
I have been working on a test system which will potentially have TestStand at its core, and downloaded/installed the 4.2.1 evaluation. Current details from the information dialog are:
TestStand Engine version 4.2.1 (4.2.1.83)
Sequence Editor Verison 4.2.1.83
The system will drive mobile radio devices using RS232 serial interfaces, usnig a variety of serial protocols (Hayes, and a couple of proprietary binary protocols for other work).
We already have in existence a soak tester, written in VS2005 with MFC unmanaged DLLs and also managed DLLs, which are mixed up together to provide different aspects of the functionality required for the binary protocols.
I have created:
1. a "master wrapper" DLL for the constellation of other DLLs - this offers up a simple C-API interface which I hope TestStand will use. It's called "SerialSessionMgr.dll""
2. a mixed managed / unmanaged "IJW" (it just works) DLL which wraps up the binary logging protocol control interfaces, which are entirely in managed C++/CLI: the "master wrapper" DLL calls into this through an unmanaged interface to create instances of the CLI-compiled class which interfaces to the underlying managed DLLs imlpementing the logging protocol. This is called "WinTseInterface.dll".
Before I started evaluating TestStand, I knocked up a test harness using CPPUnit / MFC, with which I was able to test SerialSessionMgr.dll and its' use of WinTseInterface.dll and verify they worked. The harness loads the DLL dynamically at run-time using AfxLoadLibrary() to try to emulate the way TestStand uses it.
When we open a TSE session:
My logs of the DLL loading as seen in VS2005 debug output are attached this message as PDFs
While trying to fix this, I have tried:
Solved! Go to Solution.
04-21-2011 04:22 AM
I should have pointed out in the body of my question - my CPPUnit harness works fine, but TestStand crashes. My original post contained all the information in the attachments, and the abridged version got a little "clipped".
04-21-2011 04:36 AM
Andy,
What Adapter type are you using in TestStand to invoke your code?
04-21-2011 09:04 AM
Hi there Ray.
First - many thanks for engaging with this thorny problem. Love the avatar BTW.
I've been using the C/C++ DLL adapter: the original premise of the Serial Session Manager DLL was to provide a simple C type functional interface, using simple data types, so that TestStand would be able to drive the underlying functionality easily through a single DLL.
Seeing as you've been kind enough to respond, I should explain the makeup of the DLLs a little more, I think.
The SerialSessionManager (SSMgr) DLL uses C++ and MFC internally. This is the DLL which TestStand calls into directly through the C/C++ adapter. This DLL does have one odd feature though - because the it uses the Windows Multimedia Timer (implemented in WinMM.dll) I had to artificially create a scenario where it would load the .Net mscoree DLL _before_ it loads WinMM.dll - (http://connect.microsoft.com/VisualStudio/feedback/details/329819/freelibrary-in-the-winmm-dlls-modu...), basically WinMM.dll's init code gets rather upset when .Net DLLs load, which causes the entire executable to be unloaded with subsequent crashes.
To work around this crash, the SSMgr has a single, completely empty, file which is compiled for CLR, effectively forcing a dependency into the DLL on the .Net subsystems and turning the DLL into a "IJW" binary. The resulting DLL doesn't actually have any executable managed .Net assemblies, but I'm guessing that it does contain enough .Net related stubs and information that when the DLL is loaded, mscoree.dll loads before WinMM.dll - and this means the system doesn't crash.
Now, on to the WinTseInterface DLL. My initial description of this little software system was done in something of a hurry.
This DLL is the C++/CLI "IJW" DLL which actually contains managed and unmanaged code. Underneath the WinTseInterface DLL is another system of (this time exclusively C++/CLI) DLL assemblies which implement the TSE protocol interpretation system.
When the SSMgr DLL needs to start a TSE protocol session, it calls a C-API function in the WinTseInterface which creates a new CWinTseBridge class. Here's the steps in a little more detail:
04-21-2011 09:31 AM
Hi Andy,
Is there any reason why you didn't go for a dot NET appoarch as this seems to be an interface for managed / unmanaged code?
Also, as you are evaluating TestStand 4.2.1 does this mean you already have a licenced copy of this version which is why you are not evaluating withTestStand 2010. TS2010 has improved handling of dot Net ( if you were going down this route).
Have your checked out Chapter 5 of the Reference Manual regards Adapters encase they are any issues highlighted with regards to using VS 2005.
04-21-2011 09:59 AM
I've posted my responses in-line.
Is there any reason why you didn't go for a dot NET appoarch as this seems to be an interface for managed / unmanaged code?
The serial session manager was designed to be reusable (I should have mentioned earlier) as a standard interface for applications to use the serial protocols it controls - not just TestStand - I chose a simple C interface so that a variety of languages would be able to use it fairly easily (including things like Delphi, etc).
Also, as you are evaluating TestStand 4.2.1 does this mean you already have a licenced copy of this version which is why you are not evaluating withTestStand 2010. TS2010 has improved
handling of dot Net ( if you were going down this route).
Almost - the test tool we're considering use of (the ServiceForce "Test 'n Ready" system) is using a similar version of TestStand and has shown this exception when attempting to use the DLL to start a WinTse session. I reproduced it in the evaluation copy I have and am using this as a testbed to look at possible solutions which will also work on the test tool.
I do have the installer for the TS2010 trial but the test tool won't be running that version so I'm trying to remain reasonably close to the tool.
Have your checked out Chapter 5 of the Reference Manual regards Adapters encase they are any issues highlighted with regards to using VS 2005.
I've been over chapter five a couple of times and I suspect this one's not something mentioned in there. There is a mention about using only native debugging when working on C++ code modules, but I have to used mixed mode debugging as the WinTseInterface DLL is so built...
If only the .Net adapter could call C++ code directly and not just work with assemblies... I think i may have to consider that the pure C++/CLI assembly route is the way to go, unless this mixed-mode problem can be fixed somehow.
04-21-2011 10:21 AM - edited 04-21-2011 10:22 AM
1) There is nothing TestStand related that should keep you from being able to call a mixed-mode assembly from TestStand
2) From your debug output it looks like the code you are calling is generating an unhandled exception. When debugging in Visual Studio have you tried turning on the feature under Debug->Exceptions... so that the debugger will stop when an exception is thrown? Make sure you are doing mixed mode debugging and stopping when exceptions are thrown and you will likely see the root cause of the exception in the debugger.
Hope this helps,
-Doug
04-21-2011 10:41 AM
Thanks for those Doug -
1) I figured things were OK here because we do make a call into the WinTseInterface DLL to create the unmanaged class instance we use to control the managed code from.
2) Way ahead of you (:-)) - I've already run debug with all exceptions trapped for break and there's no useful information because the debugger reckons there's no source code for the "current location". Looking at the stack trace when we break on the exception, we're waist-deep in mscorwks calls so I'm thinking it's got to do with the preamble before the function call is made. This is what makes me think I've got some kind of low-level .Net interop issue with the way the DLL is being driven from TestStand: the same binaries operate flawlessly if driven by a MFC-only CPPUnit harness framework (in debug or release targets).
I'll keep looking to see if there's something specific about the makeup of the WinTseInterface DLL which causes this issue. I'm still wondering if it's got something to do with the Serial Session Manager using a pure virtual interface to call through - it's this call (to Initialise()) which causes the WinTseInterface DLL to be loaded.
And the difference (see my original debug output window logs) between the way the CPPUnit test harness launches the WinTseInterface DLL - only one load, no (managed) - and the way TestStand loads the DLL, where it appears to load the _assemblies_...
I wonder if that second load _is_the problem... could it be that because TestStand sees there are assemblies inside the WinTseInterface DLL (I proved that TestStand can actually create and work with managed objects from the embedded assemblies inside the WintseInterface DLL) it actually calls _CorDLLMain and this completely messes up the CWintseBridge instance which we had created in the previous step?
I may delve into this idea further (I'm not even sure if _CorDLLMain exists for mixed-mode IJW DLLs) - I'm new to this low-level area of mixed-mode DLLs.
Do you guys think this sounds feasible, though? Surely this would happen all the time though - you'd call something which created stateful unmanaged objects inside a mixed-mode DLL, then make a call to anything managed, and it'd cause TestStand to reload the DLL for (managed) and nuke your stateful objects...
04-21-2011 02:48 PM
Hi Andy,
I have just run the example from here from TestStand and it ran with out any problems (correct Std Output text was captured). I am using TestStand 2010 ( as it's what I have active at the moment) and also I am just calling the exe via the Call Executable step type.
I'll rebuild the project and change it so I can use the DLL adapter.
04-22-2011 10:59 AM - edited 04-22-2011 11:00 AM
Hi Andy,
A couple more things
1) When debugging
a) Are you using the Microsoft Symbol Server? If not, please do as you will then get better callstacks with more info (names of entrypoints and more correct callstack)
b) Please copy and paste the callstack into a text file and attach to this thread.
c) Also look at callstack and see what the first function is that is in non-Microsoft code.
d) Also when it breaks on the exception can you see what the type of exeception is? Is there any specific information about the exception.
e) Also Micrsoft DLLs sometimes have expected exceptions so the first one you break on might not really be the one causing the problem since it might actually be a caught before returning to your code. You might have to continue a few times to get to the exception that is really causing the problem. NOTE: This isn't very likely though, just mentioning it just in case.
2) TestStand does not do anything so elaborate as what you are saying when it loads a DLL. Really all TestStand is doing is calling LoadLibraryEx (Windows SDK API):
http://msdn.microsoft.com/en-us/library/ms684179%28v=vs.85%29.aspx
TestStand is also using the LOAD_WITH_ALTERED_SEARCH_PATH option with that API.
Hope this helps,
-Doug