MSTest C++ unit test dll not working - c++

C# Unit Test - Runs ok
I have read the MSTest unit test (utterly useless )documentation on the microsoft website here: utterly-useless-ms-doc-link. Then I read a whole load of other more useful links (e.g. on SO) and finally I am able to run C# unit tests no problems, like this:
mstest /testcontainer:UnitTest.dll /detail:errormessage
C++ Unit Test - Fails
As far as I can tell this should be the same for the C++ unit tests, so I ran a similar command (specific command details at the end) for C++, but then I get the error:
UnitTest_TrackManager.dll Unable to load the test container
'UnitTest_TrackManager.dll' or one of its dependencies. If you build
your test project assembly as a 64 bit assembly, it cannot be loaded.
When you build your test project assembly, select "Any CPU" for the
platform. To run your tests in 64 bit mode on a 64 bit processor, you
must change your test settings in the Hosts tab to run your tests in a
32 bit process. Error details: Could not load file or assembly
'file:///D:\MiddlewareTest01\x64\Debug\UnitTest_TrackManager.dll'
or one of its dependencies. The module was expected to contain an
assembly manifest.
32-bit or 64-bit DLL?
So, fair enough, I have built the code for 64 bit and MStest is 32bit only. I used dumpbin /HEADERS fname.dll to check that this is a 64-bit file and it is:
File Type: DLL
FILE HEADER VALUES
8664 machine (x64)
D number of sections
5829E628 time date stamp Mon Nov 14 16:28:24 2016
0 file pointer to symbol table
0 number of symbols
F0 size of optional header
2022 characteristics
Executable
Application can handle large (>2GB) addresses
DLL
So, then I recompie for 32-bit and run the test again, but I get the same error. So I check that the file output (the DLL) is 32-bit and it does appear to be, here is the dumpbin for that:
File Type: DLL
FILE HEADER VALUES
14C machine (x86)
C number of sections
5829E792 time date stamp Mon Nov 14 16:34:26 2016
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
2102 characteristics
Executable
32 bit word machine
DLL
C++ Unit Test Works in the IDE
Using MSVS2015 IDE, I can compile and run my code/unit tests and they all work (when I use the x86 build) - and they all pass. If I select x64 build then it complains.
Specific Command That Fails
Here is the exact command line I am useing:
mstest /testcontainer:UnitTest_TrackManager.dll /detail:errormessage
It is run from the same location as the dll lives which is here:
D:\<somepath>\MiddlewareTest01\Debug\UnitTest_TrackManager.dll
Where <somepath> is just there to hide my PC/user details and MiddlewareTest01 is the solution folder.
As I say, I can get this to work for C# projects, but for C++ it does not seem to work in the same way.
Update
Using dependency-walker it tells me:
MICROSOFT.VISUALSTUDIO.TESTTOOLS.CPPUNITTESTFRAMEWORK.DLL was not found. Could this be an issue?

Related

Cmake Gtest project exe exits with errorcode 255

I have been using a number of c++ projects for gtest unit cases. While all these were executing fine all these years, now after updating the openssl version 1.1.1a, seeing some strange problem. Bilt in VS2017
the test project exe is not executing or not starting at all. I tried executing the exe from a command prompt. It just comes out of the execution immediately without any execution or message. It is not taking or considering any argument like --shuffle-tests.
I tried adding trace cout logs in main function but still its has no effect.
The error i get is
6: Test command: plugin-tests.exe "--gtest_shuffle" "--gtest_output=xml:TESTS-plugin.xml"
6: Test timeout computed to be: 10000000
6/8 Test #6: plugin-tests ...........***Failed 0.01 sec
I am helpless in debugging in the gtest exe as there are no proper documentation for this as well.
Could any body please shed some light on this ?
It has the standard GTest functions to init and runn all tests. This has been working all these years.
The change i made in the code is,
Modified
EVP_CIPHER_CTX m_context_encrypt
to
EVP_CIPHER_CTX *m_context_encrypt
and did
m_context_encrypt = EVP_CIPHER_CTX_new()
as per the structure changes in openssl1.1 onwards.
And, the openssl is statically linked to the project exe which required two of the windows libraries to be linked with
crypt32 ws2_32
so added those dependency the cmake like,
if( WIN32 )
target_link_libraries(${PROJECT_NAME} crypt32 ws2_32)
endif()
The gtest unit test cases are executing successfully in linux build.
The problem is with the windows execution.
However out of 8 test projects, one test project is able to execute properly in windows, and i find no difference in the cmake files.
It is kindof strange
Note: Exit code of the exe seems to be 255

Dealing with decorated external binaries when building a package with Rcpp

I am using a Window 32-bit machine to compile an R package developed using Rcpp and compiled with Rtools 3.4 in RStudio 1.0.28. I keep getting an error about the # signs within the 32-bit external dll (NYCgeo.dll):
thefile.o:thefile.cpp:(.text+0x913): undefined reference to `_imp__NYCgeo#8'
collect2.exe: error: ld returned 1 exit status
Sure enough, when I opened the 32-bit NYCgeo.dll in a text editor, I found #8 suffix. This is weird because when I developed the 64-bit version, the 64-bit NYCgeo.dll did not contain #8 suffix and I did not have any errors. Anyway, I read about the --kill-at command and was wondering where I would include it. I tried RStudio's Configure Build Tools settings as well as my makevars.win.in file but had no luck.
Response to #Dirk
Updated title as requested.
I am compiling the package from within RStudio using Rtools so I assumed it might have something to do with RStudio's Project Options.
I have spent the past week checking existing documentation. This post, this post, and this post describe the issue I am having. My issue is that I do not know where to specify either "--kill-at" or "--add-stdcall-alias"
The whole point of my package is to leverage NYC Dept of City Planning's geocoding software. I did not "just throw" the binary NYCgeo.dll "into the mix." In fact, my 64-bit version of the package works fine. My issue is with developing the 32-bit version... specifically, the presence of an #8 suffix in the NYCgeo.dll binary which is causing an error.
NYCgeo.dll is a C binary. I am not using Visual Studio.
The previous question you mentioned dealt with creating Makevars files for the 64-bit version of my package (thanks again, #Coatless for providing useful information). The 64-bit NYCgeo.dll binary did not contain an #8 suffix.
UPDATE:
I tried to create a better title for this question. The question pertains to creating an R package which utilizes functionality from another piece of software... in my case, geocoding software. Specifically, the issue I experienced is that the 32-bit version of the geocoding software has a decorated dll files while the 64-bit version does not. A decorated binary contains # symbols which trigger an error during compiling. My task was to devise a way to demangle (not sure if that is a real word) the 32-bit dll but leave the 64-bit dll alone.
Many thanks.
Gretchen
The rJava package was incredibly helpful in understanding how to deal with decorated binaries.
I created a def file named NYCgeo.def and saved it in my src directory:
LIBRARY NYCGEO.DLL
EXPORTS
NYCgeo#8
I then updated my Makevars.win.in file which is also in my src directory:
GBAT_PATH = #GBAT_PATH#
GBAT_DLL = #GBAT_DLL#
PKG_LIBS = -L"$(GBAT_PATH)/Bin" -l$(GBAT_DLL)
PKG_CPPFLAGS = -I"$(GBAT_PATH)/Include"
ifeq "${R_ARCH}" "/i386"
$(SHLIB): $(OBJECTS) NYCGEO.a
NYCGEO.a: NYCGEO.def
$(DLLTOOL) -k -d NYCGEO.def -l NYCGEO.a -D "$(GBAT_PATH)/Bin/$(GBAT_DLL)" $(DT_ARCH)
endif
I am now able to compile the package on both 32-bit and 64-bit machines running Windows.

How to create a redistributable DLL that will work on other computers

I'm trying to create a GUI that will try to interface with CAN peripherals connected to the computer and allow communication between the computer and a microcontroller. Most of the work is done in Java, but the CAN code is written in C++, and called from Java using JNI. I'm working with Visual Studio 2013 for the C++, and Eclipse for the Java.
The program works fine on the development computer, but I'm inexperienced with creating DLL's, and I can't get the program to run on another computer. I've used Dependency Walker to get an idea of what DLL's I should bundle with the application, and at this point I've included all the DLL's that it said were missing (there are a few it says are still missing, but it says these are missing on the development computer as well, and I believe this is just a problem with Dependency Walker).
The application folder contains a runnable jar file of the GUI, the DLL I created, and the dependent DLL's. I try to run the application from the command-line with "java -jar {application.jar}". I get the following error:
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: C:\Users\David\Dropbox\ATPBoardInterface\CANMessager7.dll: A dynamic link library (DLL) initialization routine failed
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1939)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1864)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1854)
at java.lang.Runtime.loadLibrary0(Runtime.java:845)
at java.lang.System.loadLibrary(System.java:1084)
at model.CANController.<clinit>(CANController.java:34)
at main.Main$1.run(Main.java:70)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:721)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:682)
at java.awt.EventQueue$3.run(EventQueue.java:680)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:691)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)
I'm looking for suggestions on how to resolve this issue. Something that I can share with any other Windows computer that will be easy for the end user to install and run.
Edit: If it makes any difference, the program relies on the use of National Instruments' CAN software. I've included a number of DLL's in the application folder related to this which Dependency Walker listed, but I'm not sure if that's enough. Maybe the target computer will need certain National Instruments software already installed for it to work, and if it's missing, that may be causing the DLL initialisation failure? I'm not familiar enough in this kind of area to be sure either way though.
Edit 2: This is what I've bundled inside my application folder:
20/08/2013 10:56 <DIR> .
20/08/2013 10:56 <DIR> ..
20/08/2013 08:26 427,170 ATPBoardInterface.jar
20/08/2013 09:28 182,928 CANMessager.lib
20/08/2013 08:52 201,728 CANMessager7.dll
15/08/2013 16:28 30,720 CANMessagerXP.dll
16/06/2013 21:11 966,224 msvcr120.dll
11/07/2006 18:35 348,160 msvcr71.dll
13/10/2012 11:00 655,872 msvcr90.dll
01/06/2011 17:59 45,192 Nican.dll
06/04/2010 17:44 72,224 NicanCfq.dll
06/04/2010 17:44 125,472 nicanDBA.dll
01/06/2011 17:59 197,784 NIcanFrm.dll
01/06/2011 17:59 18,080 NIcanpu.dll
01/06/2011 17:59 61,568 NicanTsk.dll
26/01/2012 15:54 19,632 nipal32.dll
26/01/2012 16:11 309,920 nipalu.dll
26/01/2012 15:53 12,968 nipalut.dll
19/08/2013 16:18 772 README.txt
20/08/2013 08:34 <DIR> res
20/08/2013 10:56 0 temp.txt
20/08/2013 09:43 6,494,784 vcredist_x86.exe
19 File(s) 10,171,198 bytes
3 Dir(s) 416,406,867,968 bytes free
I'm not sure which of these are necessary.
One problem could be a 32-/64-bit problem.
If your CAN interface DLL is a 32 bit DLL and you are running 64 bit Java this will not work. Running 64 bit DLLs with 32 bit Java will not work either.
The only solution would be to compile the DLL as 32 and 64 bit version and deliver both DLL versions.
If the 32/64 bits is not the problem you could use the SysInternals ProcessExplorer tool to see all file access attempts. In this case you would see if Java tries to access any DLL file that is not present.
A solution for the 32-/64-bit problem would be the use of a command line EXE file instead of a DLL file. The data is transferred using the standard output and input (on the C++ side) and using the InputStream and OutputStream of the java.lang.Process class on the Java side. This will always work with a 32 bit EXE file.

Running native VS2012/C++ 64-bit unit tests from command line

I'm attempting to run unit tests from the command line. I tried using the mstest.exe program using the following command:
E:\VS Projects\...\>"C:\Program Files (x86)\Microsoft Visual Studio 11.0\
Common7\IDE\MSTest.exe" /testcontainer:mytest.dll
/testsettings:"E:\VS Projects\...\Local.testsettings"
The mstest program responce was:
Microsoft (R) Test Execution Command Line Tool Version 11.0.50727.1
Copyright (c) Microsoft Corporation. All rights reserved.
Loading E:\VS Projects\...\Local.testsettings...
Loading mytest.dll...
mytest.dll
Unable to load the test container 'mytest.dll' or one of its
dependencies. If you build your test project assembly as a 64 bit assembly,
it cannot be loaded. When you build your test project assembly, select "Any
CPU" for the platform. To run your tests in 64 bit mode on a 64 bit
processor, you must change your test settings in the Hosts tab to run your
tests in a 32 bit process. Error details: Could not load file or assembly
'file:///E:\VS Projects\...\mytest.dll' or one of its dependencies. The
module was expected to contain an assembly manifest.
Local.testsettings does include information, that the tests shall be run in 64-bit environment.
I can guess, that mstest expects an assembly instead of native test project and this is why it fails. If so, how can I run native tests from the command line? In the other case, how shall I configure the mstest to work properly?
Thanks for Hans Passant for guidance.
The solution is to use:
C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe
Another option is to install Catch2 which allows you to run the unit testing project as an exe from the command prompt and display the results:
https://github.com/catchorg/Catch2
C:\Projects\T9Predict\T9PredictTests\Debug\> T2PredictTests.exe
T2PredictTests.exe
C:\Projects\T9Predict\T9PredictTests\T2PredictTests.cpp(33): FAILED!
REQUIRE( result[0] == "hello" )
with expansion:
"" == "hello
===============================================================================
test cases: 2 | 1 passed | 1 failed
assertions: 2 | 1 passed | 1 failed

DOS-reported error: Bad file number

I have a batch file that tries to compile a static library using Borland C++ Builder 6.0
It is called from Borland make (makefile created with bpr2mak) which is called from a .bat file (used to compile the whole project with Visual Studio and some Borland C++ Builder legacy projects), which is called from a bash shell script running inside Cygwin.
When I run the .bat file directly from a Cygwin shell, it runs OK, but when its being run from a Program calling cygwin with Boost::Process::launcher I'm getting this error:
C:\ARQUIV~1\Borland\CBUILD~1\Bin\..\BIN\TLib /u bclibs.lib #MAKE0000.###
DOS-reported error: Bad file number
TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation
opening 'MAKE0000.###'
** error 1 ** deleting bclibs.lib
It's a complicated scenario, but this Program which calls cygwin is run whenever we need to build our software package which needs to be build for various Linux distos and Windows 32 and 64-bit.
Note: It's the only Borland Project failing, the other compile just fine (it's the only static library using borland also, so it can be some problem with the TLib tool.
The problem was that TLib does not like to have his output redirected (seen here) without having an input pipe as well. Solved by creating an input pipe to in the Boost::Process::launcher using set_stdin_behavior
I'm just guessing here, but this may have to do with long filenames and/or spaces in paths.
1) Modify your makefile so it would save current environment to a file, immediately before executing the failing command (set > d:\env.txt & echo CD=%CD% >> d:\env.txt). Then run it both ways (directly and via program) and compare the environments of good run and bad run.
2) Using filemon from Sysinternals, capture logs of disk access in both cases (these logs are going to be huge, though you can uncheck everything except Open in the filter to reduce the size). Again, compare and check for clues...
3) Try instaling everything involved to paths conforming to 8.3 scheme.
This error is not related to C++ itself. It happens when your build script opens too much files (more than defined in DOS command processor environment). To resolve this issue try to set value of files variable to 253. For Windows XP this variable defined in the file %WINDIR%\system32\config.nt.
files=253
Seems it is known bug in Borland C++ tools. Here is description and possible workaround for this issue:
Problem: Some static Lib projects will
not link correctly when compiled. You might see something
like this :
J:\Borland\CBUILD~1\bin\..\BIN\TLib /u debug\jpegD.lib #MAKE0000.###
DOS-reported error: Bad file number
TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation
opening 'MAKE0000.###'
** error 1 ** deleting debug\jpegD.lib
MAKE failed, returned : 1
Workaround : In some cases (where the "Bad file number" error is seen) it may be possible to work around this by specifying -tDEFLIB.BMK in the BPR2MAKE Options field, and Turning off the "Capture Make Output" option.
I have not tested it, but I hope that helps.