Search code examples
c++visual-studiounit-testingmfc

When running a test with GoogleTest, an SEH exception occurs with a simple variable definition


When I ran a unit test using the following procedure, an exception occurred with a simple declaration such as "CString a;". The environment is Visual Studio 2019 and the language is C++.

  • Boot VisualStudio2019
  • Click "Create a new project"
  • Select "MFC App", Click "Next"
  • Set an arbitrary folder for the "Location" item, and click "Create" with the other defaults.
  • Leave everything as default and click "Finish".
  • A project with the default name "MFCApplication1" will be created.
  • Right-click the "MFCApplication1" project in "Solution Explorer" and click "Properties".In "Configuration Properties">"General">"General Properties", set "ISO C++17 Standard(/std:c++17)" in "C++ Language Standard" item.
  • Right-click the "MFCApplication1" project in "Solution Explorer" and click "Properties".In "Configuration Properties">"Advanced">"Advanced Properties", set "Use MFC in a Shared DLL" in "Use of MFC" item and set "Use Multi-Byte Character Set" in "Character Set" item. increase.
  • Add "SampleClass.cpp" and "SampleClass.h" to your project.

SampleClass.h

#pragma once


class _DllExport SampleClass
{
public:
    SampleClass(void);
    virtual ~SampleClass(void);
    char*   sampleMethod();
protected:
private:
};

SampleClass.cpp

#include "pch.h"
#include <string.h>

#include "SampleClass.h"


SampleClass::SampleClass(void) {
}

SampleClass::~SampleClass(void) {
}

char*   SampleClass::sampleMethod() {
    CString a;
    return "test";
}
  • Add code to pch.h
#define _DllExport   __declspec( dllexport )
  • Build the project and make sure it completes without errors.
  • Right-click on the solution in "Solution Explorer" and click Add>New Project...
  • Select "Google Test" and click "Next".
  • Leave all defaults in "Configure your new project" and click "Create".
  • Select "MFCApplication1" at "Select project to test" in "Test Project Configuration" and click "OK" with other items as default.
  • A new test project is added with the name "Sample-Test1".
  • Right-click the "Sample-Test1" project in "Solution Explorer" and click "Properties".In "Configuration Properties">"General">"General Properties", set "ISO C++17 Standard(/std:c++17)" in "C++ Language Standard" item.
  • Right-click the "Sample-Test1" project in "Solution Explorer" and click "Properties".In "Configuration Properties">"Advanced">"Advanced Properties", set "Use MFC in a Shared DLL" in "Use of MFC" item and set "Use Multi-Byte Character Set" in "Character Set" item. increase.
  • Right-click the "Sample-Test1" project in "Solution Explorer" and click "Properties". Add "$(ProjectDir)..\MFCApplication1\Debug\MFCApplication1.lib" to "Additional Dependencies" item of "Configuration Properties">"Linker">"Input".
  • Add the following code to the "Sample-Test1" project.

test.cpp

#include "pch.h"
#include "..\MFCApplication1\SampleClass.h"

TEST(TestCaseName, TestSampleMethod) {
    SampleClass sampleClass;
    char* value = sampleClass.sampleMethod();
    EXPECT_TRUE(strcmp(value, "test") == 0);
}
  • Add code to pch.h of "Sample-Test1" project
#define _DllExport   __declspec( dllimport )
  • Run the build and make sure it completes without errors.
  • Right-click the "TestName" item displayed in "Test Explorer" and click "Debug" to debug the test method.
  • Then you get an SEH exception at a nondescript code like "CString a;". In addition, exceptions will occur at runtime when defining variables such as "std::vector<int>" and processing such as "memset" and "printf".
Exception thrown at 0x80000142 in Sample-Test1.exe: 0xC0000005: Access violation executing location 0x80000142.

unknown file: error: SEH exception with code 0xc0000005 thrown in the test body.

A simple test does not pass in a project created with almost default settings. Do I need to configure anything else? Ultimately, I want to complete the test without any problems with the following code. All of these raise exceptions when running unit tests.

  • Adding variables like "CString" or "std::vector<xxx>" to member variables

  • Using local variables for variables like "CString" or "std::vector<xxx>"

  • Using standard library functions such as "memset" and "vsprintf_s"

  • I tried with the following versions. VS2019 Professional(v16.11, v16.7) and VS2022. However, none of the versions fixed the problem. I hope it will work in the VS2019 Professional environment.

  • I tried not only Google Test but also a native unit test project, but it did not resolve.


Solution

  • From the doc: Link to object or library files

    add the output .obj or .lib files to the dependencies of the test project.

    When you are using not library project you should link to obj file. And remove _DllExport. For MFC project, you should link->input: SampleClass.obj and PCH.obj in your GTest Project. The obj files are in folder: MFCApplication1\x64\Debug