I wrote a simple unit test that calls an exported function within an EXE that searches for the first space in a string. When I attempt to call it, the internal call to memchr gets an access violation. Calling _CrtCheckMemory() fails with an access violation as well.
My guess is that the CRT (C Run-Time) is not initialized in the EXE which is loaded by the unit test. I moved the function to a DLL and it works perfectly.
While I have a workaround, I'd like to understand how to get the original unit test working while testing a function from an EXE.
To repro:
- Create a new C++ console app from VisualStudio 2022 called AccessViolation
- Add a native unit test called AccessViolationTest
- Replace main() with
// AccessViolation.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
include <iostream>
include <string>
include <assert.h>
__declspec(dllexport) size_t TestFromExe(const std::string& test)
{
assert(_CrtCheckMemory()); // this fails
size_t index = test.find(' '); // comment previous line and this fails
return index;
}
int main()
{
std::string test = "The quick brown fox jumped over the lazy dog's back";
std::cout << "found at index " << TestFromExe(test);
}
- Replace unit test with
include "pch.h"
include "CppUnitTest.h"
include <string>
include <assert.h>
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
__declspec(dllimport) size_t TestFromExe(const std::string& test);
namespace AccessViolationTest
{
TEST_CLASS(AccessViolationTest)
{
public:
TEST_METHOD(TestMethod1)
{
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_CHECK_ALWAYS_DF);
assert(_CrtCheckMemory());
std::stringstream str;
std::string test = "The quick brown fox jumped over the lazy dog's back";
size_t index1 = test.find(' ');
size_t index2 = TestFromExe(test);
str << "index found at " << index1 << " and " << index2;
Logger::WriteMessage(str.str().c_str());
}
};
}
- Modify the properties of the unit test project to add the EXE .lib: Linker -> Input -> Additional Dependencies: $(OutDir)AccessViolation.lib
- Only fails from running the unit test. Console app succeeds.