Unit Tests fail with exception code c0000005 - c++

I am trying to create Unit Tests in Visual Studios 2012 using a Native Unit Test Project.
This is the test I have:
TEST_METHOD(CalculationsRoundTests)
{
int result = Calculations::Round(1.0);
Assert::AreEqual(1, result);
}
Exporting the Class:
#ifdef EXPORT_TEST_FUNCTIONS
#define MY_CALCULATIONS_EXPORT __declspec(dllexport)
#else
#define MY_CALCULATIONS_EXPORT
#endif
...
class CALCULATIONS_EXPORT Calculations {
...
public:
static int Round(const double& x);
The function itself:
int Calculations::Round(const double& x)
{
int temp;
if (floor(x) + 0.5 > x)
temp = floor(x);
else
temp = ceil(x);
return int(temp);
}
However, the test nearly always fails with error code c0000005 (Access Violation).
The test will fail the first time that x, or any other variable that may be declared in the function, is used.
I followed the instructions at Unresolved externals when compiling unit tests for Visual C++ 2012

This is a known bug. Unfortunately, Microsoft considers this as "Won't Fix".
In short, there are two workarounds:
Compile the actual project in release mode and the test project in debug mode.
Outsource all testable functions to a static library project.

I never figured out why the test would cause an access violation when it was run; however, I'm sure I had set something up wrong.
To remove this error, I changed the structure of my Visual Studio solution to have the majority of the code be in a static library (.lib) project which will contain the implementation of my program. By doing this, all of the classes and functions for my program in the project are automatically exported, so I don't need to use __declspec(dllexport).
Then, I created a small Win32 Console Application, which will create the .exe file for my program, that references the .lib project. The purpose of this project is to create the executable file for my program, so all it needed was a main that would call the start of my code in the .lib project.
After I did this, I was able to get the Native Unit Test project to work easily by just getting it to also reference the .lib project, and I haven't had any access errors since.

Related

C++ unitTest with LinkTime substitution

I'm reading "Test-Driven Development for Embedded C," by James W. Grenning.
I'd like to reproduce case with "Link-Time Substitution" using Visual Studio Community 2019 and gTest.
I have the following code:
production_code staticly linked library
foo.cpp
#include "foo.h"
int foo(int x) {
return x + 1;
}
foo.h
#ifndef _foo_
#define _foo_
int foo(int x);
#endif //_foo_
In gtest project production_code library is included via reference
test.cpp
#include "gtest\gtest.h"
#include "gmock\gmock.h"
#include "..\prod\foo.h"
//fake implementation of production code foo
int foo(int x) {
return x - 1;
}
TEST(TestCaseName, TestName) {
auto x = foo(5);
EXPECT_EQ(x, 4);
}
The linker gives me following error:
1>prod.lib(foo.obj) : error LNK2005: "int __cdecl foo(int)"
(?foo##YAHH#Z) already defined in test.obj 1>C:\Example\prod_test.exe
: fatal error LNK1169: one or more multiply defined symbols found
What have I missed here? Why doesn't this work?
If I add the command "/FORCE:MULTIPLE" to linker, then I get only warning, but I think that this is not the right approach to doing this.
This situation occurs because you defined foo(int) in 2 places: foo.cpp and test.cpp and you build your code with this files. If you need to run some test with a stub (fake function foo(int) in this case) you need to create 2 targets of build for:
building of your real application
building of a special application for unit testing (and than run it)
And when you build the application for unit testing, you link it with test.cpp (but not with foo.cpp). Also when you build your real application you link it with foo.cpp (but not with test.cpp).
Note: it's make sense to test real code and create a stub when this stub provides some additional functionality according to idea of a test (for example, you check your sort() function but you can use stub to generate data for sort() because the data are provided after some complex algorithm finished working and the computing takes a lot of time) or you don't want to use some resources (for example, you check your sort() function but you use a network connection to a server to get real data for sort()) or you need to provide some specific data for testing you algorithm (for example, to check a corner case using specific data; or maybe you have found the sort() doesn't work with specific data). But again, it's make sense to test real code.

Code coverage error (No binaries were instrumented)

Problem:
Microsoft Visual Studio Enterprise 2015
Version 14.0.25431.01 Update 3
I'm attempting to use the code coverage function but it returns this error:
Empty results generated: No binaries were instrumented. Make sure the
tests ran, required binaries were loaded, had matching symbol files,
and were not excluded through custom settings. For more information
see http://go.microsoft.com/fwlink/?LinkID=253731
My .coverage file is full of non-sense, starting with "PCHÿ". I thought my problem looked similar to this one: Issue with Code Coverage in VS 2012, but deleting the .suo file and running Visual Studio in admnistrator didn't solve anything.
How to replicate:
1) Create new empty project "MyProject"
2) Add new file "Calculator.hpp"
#pragma once
class Calculator
{
public:
int add(int a, int b);
int sub(int a, int b);
};
3) Add new file "Calculator.cpp"
#include "Calculator.hpp"
int Calculator::add(int a, int b)
{
return a + b;
}
int Calculator::sub(int a, int b)
{
return a - b;
}
4) Add new file main.cpp
#include "Calculator.hpp"
#include <iostream>
using std::cout;
int main()
{
Calculator calc;
std::cout << calc.add(5, 11) << std::endl;
std::cout << calc.add(11, 1) << std::endl;
return 1;
}
5) Build solution. (0 errors)
6) Add new test project to solution as explained here: https://msdn.microsoft.com/en-us/library/hh419385.aspx#objectRef:
Add new Native Unit Test Project to solution "CalculatorUnitTest"
Add "main.obj" and "Calculator.obj" to Linker/Input/Additional Dependencies of "CalculatorUnitTest"
Add path to obj files to Linker/General/Additional Library Directories of "CalculatorUnitTest". (In my case: D:\JF\Programming\Tests\MyProject\MyProject\Debug)
Add the header directory of "MyProject" to VC++ Directories/Include Directories. (In my case: D:\JF\Programming\Tests\MyProject\MyProject).
7) Replace code in "unittest1.cpp" with:
#include "stdafx.h"
#include "CppUnitTest.h"
#include <Calculator.hpp>
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace CalculatorUnitTest
{
TEST_CLASS(UnitTest1)
{
public:
TEST_METHOD(TestMethod1)
{
Calculator calc;
Assert::AreEqual(5, calc.add(2, 3));
}
};
}
8) Build solution (0 errors, TestMethod1 appear in Test Explorer)
9) Right-click TestMethod1, "Run Selected Tests" (Test successfully passes)
10) Right-click TestMethod1, "Analyze Code Coverage for Selected Tests" (Code coverage fails).
At D:\JF\Programming\Tests\MyProject\Debug, I have both my MyProject.exe and MyProject.pdb with the CalculatorUnitTest.dll.
First of all, I am not sure if Visual Studio 2015 (C++) supports ".exe" type project for the unit test. But you are using ".obj" directly from your project. You need to place ".pdb" file in the same folder.
I created a static library project and added the unit test. Same problem on my environment.
Future here. Same problem, except my test target is a Static Library project in the same Solution.
MyLib - Code that will be tested.
MyLibTests - Project containing the tests.
Solution contains both projects.
MyLibTests has project Reference to MyLib.
<OutDir> (in .vcxproj) aka Output Directory aka $(OutDir) identical in both projects. (My value <OutDir>$(SolutionDir)$(Configuration)_$(Platform)\</OutDir>)
On your test project (MyLibTests), go
Properties
Select [Debug|platform]
Linker
Debugging
Generate Debug Info = Optimize for debugging /DEBUG
Mine was initially set for /DEBUG:FASTLINK.
Via this social MSDN post I figured it had something to do with the PDB, because MSDN (aka now "learn.microsoft.com") said this is an important step in several places, and I assume PDB are used trace calls, I assume using DbgHelp.dll.
And this sort of checklist modified from another social MSDN post:
Test project References properly set (MyLib.lib is in the same Solution as MyLibTests.dll)
Build order/dependency set/verified.
I also have Autorun on Build.
Rebuild (this should rebuild dependencies).
made sure all test were run(all test run successful)
not using optimisation (Profile Guided/Instrumentation etc).
<OutDir> aka Ouput directory should be the same, where both MyLibrary.lib/dll/exe ends up with their MyLibrary.pdb since PDB paths are linked in the exe/dll.
not using a runsettings file
Unload all other projects other than affected ones

Inconsistent build when a function template is modified in the header file underVS2012

I have a visual studio solution that uses multiple projects. I find a strange behavior with compiling/linking using VS2012 under debug mode. I have a project 'X', and it has a header file "A.h" contains
template <class T>
double Test( const T & in) //first function
{
std::cout<<"1\n";
return 0.0;
}
template <class T>
T Test( const T & in, const bool in) //second function
{
std::cout<<"2\n";
return T(0.0);
}
void dTest(dataType in)
{
Test(in)
}
void TTest(dataType in);
and "A.cpp"
#include "A.h"
void TTest(dataType in)
{
Test (in, true);
}
Then some where in the solution I call TTest and dTest.
It prints 1 and 2 as expected.
Then I change code to print 3 and 4 respectively;
and build, which leads to compilation of A.cpp.
However when I run it prints 3 and 2.
It I try to place a break point in the first function it reaches there.
However if I set break point in the second function, the debugger complains "break point will not be hit. Source code version is different".
I could not reproduce this behavior in "release" mode, yet. Doing a rebuild brings correct behavior. Why do I see this behavior? There is a single dll file created for each project. How can it have part from current code and part from previous code?. I am working with TFS systetm. Does this mean, VS keeps an intermediate file that is different from my current file?
Any insights/solution to the problem (apart from rebuild/clean) appreciated
Thanks
Visual Studio doesn't do a good job of tracking dependencies. See How do I make sure that when a .h file is modified, the .cc files including it are compiled automatically in a Release build using Visual Studio 2008?.
If you modify a .h file, the only safe method to make sure that the change takes effect is to rebuild all the projects in the solution.
PS
In my experience, the dependencies get picked up correctly in debug builds. The problem is only in release builds.

Heap error with Google mock test framework

If you download the latest version of Google Mock (1.7.0) there are project files for VS2005 and 2010! The project to test is written in VS2008,so I opened the VS2005 file and converted it for VS2008 and compiled with
Multi-threaded Debug (/MTd)
Dynamic Library (.dll)
In the test solution:
Project to test:
Configuration type: Dynamic Library (.dll)
Runtime library: Multi-threaded Debug (/MTd)
UnitTest project:
#include <iostream>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
int main(int argc, char **argv)
{
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
Additional Library Directories: ..\..\gmock\msvc\2005\Debug
Additional Dependencies: gmock.lib gmock_main.lib
Runtime library: Multi-threaded Debug (/MTd)
If I run the UnitTest project I get following error:
Windows has triggered a breakpoint in Program_UnitTests.exe.
This may be due to a corruption of the heap, which indicates a bug in Program_UnitTests.exe or any of the DLLs it has loaded.
in xmtx.c:
_RELIABILITY_CONTRACT
void __CLRCALL_PURE_OR_CDECL _Mtxunlock(_Rmtx *_Mtx)
{ /* unlock mutex */
LeaveCriticalSection(_Mtx);
#ifdef _M_CEE
System::Threading::Thread::EndThreadAffinity();
#endif
} // <------- STOPPED HERE
#endif /* !_MULTI_THREAD */
What is wrong here? Thank you for any help!
Super-short answer: compile googlemock as a static library instead of a dll; that might fix your problem.
Much longer answer:
Problems like this are typically the result of mismatched compiler settings. These kinds of problems are a pain to diagnose, which is a large part of the reason for the following guidance given in the googletest FAQ:
If you compile Google Test and your test code using different compiler flags, they may see different definitions of the same class/function/variable (e.g. due to the use of #if in Google Test). Therefore, for your sanity, we recommend to avoid installing pre-compiled Google Test libraries. Instead, each project should compile Google Test itself such that it can be sure that the same flags are used for both Google Test and the tests.
This applies equally to googlemock. Basically, they're suggesting that you compile the googletest & googlemock source code alongside your own code to avoid this problem. They also make this quite easy: check out the fused-src directory of the gmock distribution for a voltron .cc file and the corresponding headers, gmock.h and gtest.h.
If you'd like to continue linking against a completely separate library, you'll need to verify that all of the compiler settings match in the VS project. Basically you'll need to check every single configuration in the properties dialog, paying special attention to the toolset, exceptions, preprocessor definitions, RTTI, etc.

Using C++ app in .NET

I am new to using PInvoke with Classic C++ and I asked this question yesterday: Using Windows API functions in .NET
I have now created a very simple C++ program as follows:
#include <iostream>
#include <stdio.h>
#include <string>
extern "C" __declspec(dllexport) int hello()
{
//printf ("Hello World!\n");
return 1;
}
I then compiled the DLL using the following command: g++ -c mydll.cpp
Then created the shared library using the following command: g++ -shared -o mydll.dll mydll.o, then copied mydll.dll to C:\Windows\syswow64.
I then created a new VB.NET project and created the following code:
Imports System.Runtime.InteropServices
Public Class TestPlatformInvoke
<DllImport("mydll.dll", CallingConvention:=CallingConvention.Cdecl)> _
Public Shared Function hello() As Integer
End Function
Public Sub New()
Try
Dim test As Integer = hello() 'Line 6 ex As Exception
'I don't swallow exceptions
MsgBox("test")
Catch ex As Exception
End Try
End Sub
End Class
The application exits after calling hello(). It does not throw an exception.
I am trying to get to grips with how this works. I don't have any commercial experience with c++; only academic experience at university.
Here is an image of Dependancy Walker for mydll.dll.
Declare is VB6 legacy. You should use p/invoke and the DllImport attribute.
<DllImport("mydll.dll", CallingConvention:=CallingConvention.Cdecl)> _
Public Shared Function hello() As Integer
End Function
There are lots of ways that this could fail. Perhaps the DLL is not loading because there's a 32/64 bit mismatch. Also, your calling conventions do not match. Your DLL will be using cdecl but your VB code uses stdcall. The pinvoke above fixes that.
Most seriously your function does not appear to have been exported from the DLL. That's going to make it fail for sure. Use Dependency Walker to determined whether or not your function has been exported. I'm not so familiar with g++ so you'll have to work out how to export your function using the GNU toolchain. But watch out for name decoration and name mangling. You may need to take care with how you export your function so that it is exported with the desired name.
If you use Visual Studio to debug programs and include the DLL in your project (Visual Studio 2012 Express Edition allows including projects of different types in the solution), you may set the "Allow native code debugging" option to automatically switch the debugger from the VB.NET to C++, when you P/Invoke function from the DLL.
Here's a working Proof-of-concept. Simply unzip, open in Visual Studio, build and run. You may compare this program with your project and find the differences, which makes your code failing.
I guess, that you haven't actually exported the function from the DLL. Simply including it in the DLL's code may not be enough: check, which functions are exported from the DLL using the Dependency Walker (other link) program. For example, I had to add folowing declaration:
__declspec(dllexport) int __stdcall Test() { ... }
And additionally create the .def file for the names for exported functions not to be decorated.
Try to modify your DLL source code and change the function declaration to:
extern "C" __declspec(dllexport) int hello()
{
return 1;
}