Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Factor out code that should move to cxplat #82

Merged
merged 15 commits into from
Aug 20, 2023
Merged
5 changes: 3 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
BUILD_CONFIGURATION: ${{matrix.configurations}}

BUILD_PLATFORM: x64
USERSIM_MEMORY_LEAK_DETECTION: true
CXPLAT_MEMORY_LEAK_DETECTION: true

steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -70,7 +70,7 @@ jobs:
BUILD_PLATFORM: x64
CMAKE_GENERATOR: Visual Studio 17 2022
PLATFORM_TOOLSET: v143
USERSIM_MEMORY_LEAK_DETECTION: true
CXPLAT_MEMORY_LEAK_DETECTION: true

steps:
- uses: actions/checkout@v3
Expand All @@ -96,4 +96,5 @@ jobs:
working-directory: ./build/bin/${{env.BUILD_CONFIGURATION}}
shell: cmd
run: |
.\cxplat_test -d yes
.\usersim_tests -d yes
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${TARGET_PLATFORM}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release)

add_subdirectory("cxplat")
add_subdirectory("src")
add_subdirectory("usersim_dll_skeleton")
add_subdirectory("sample")
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ To use this repository from another project:

### Leak Detection

To detect memory leaks on exit, define the environment variable USERSIM_MEMORY_LEAK_DETECTION=true
To detect memory leaks on exit, define the environment variable CXPLAT_MEMORY_LEAK_DETECTION=true

### Fault Injection

To use fault injection, define the environment variable USERSIM_FAULT_INJECTION_SIMULATION=4
To use fault injection, define the environment variable CXPLAT_FAULT_INJECTION_SIMULATION=4
where the value (4 in this example) is the number of stack frames to use to determine whether a call stack is unique.
Fault injection will cause one call into the UserSim library to fail, for every unique call stack.

Expand Down
5 changes: 5 additions & 0 deletions cxplat/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright (c) Microsoft Corporation
# SPDX-License-Identifier: MIT

add_subdirectory("cxplat_test")
add_subdirectory("src")
35 changes: 35 additions & 0 deletions cxplat/cxplat_test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright (c) Microsoft Corporation
# SPDX-License-Identifier: MIT

Include(FetchContent)

FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.0.1 # or a later release
)

FetchContent_MakeAvailable(Catch2)

add_executable(cxplat_test
cxplat_memory_test.cpp
)

target_include_directories(cxplat_test PRIVATE
"${CMAKE_BINARY_DIR}/generated-includes/"
"${CMAKE_BINARY_DIR}/_deps/catch2-src/src/"
"${CMAKE_CURRENT_SOURCE_DIR}/../inc/"
"${CMAKE_CURRENT_SOURCE_DIR}/../inc/winuser"
)

target_link_directories(cxplat_test PRIVATE
"${CMAKE_BINARY_DIR}/lib/${CONFIG}"
)

target_link_libraries(cxplat_test PRIVATE
"cxplat_winuser.lib"
"ntdll.lib"
Catch2::Catch2WithMain
)

add_dependencies(cxplat_test cxplat_winuser)
90 changes: 90 additions & 0 deletions cxplat/cxplat_test/cxplat_memory_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT

#define CATCH_CONFIG_MAIN
#if !defined(CMAKE_NUGET)
#include <catch2/catch_all.hpp>
#else
#include <catch2/catch.hpp>
#endif
#include "cxplat.h"

#define TEST_TAG 'tset'

TEST_CASE("allocate", "[memory]")
{
// Try an allocation that need not be cache aligned.
uint64_t* buffer = (uint64_t*)cxplat_allocate_with_tag(CxPlatNonPagedPoolNx, 8, TEST_TAG, false);
REQUIRE(buffer != nullptr);
REQUIRE(*buffer != 0);
*buffer = 0;
cxplat_free(buffer);

// Try an allocation that must be cache aligned.
buffer = (uint64_t*)cxplat_allocate_with_tag(CxPlatNonPagedPoolNxCacheAligned, 8, TEST_TAG, false);
REQUIRE(buffer != nullptr);
REQUIRE(*buffer != 0);
REQUIRE((((uintptr_t)buffer) % 64) == 0);
*buffer = 0;
cxplat_free(buffer);

// Try an allocation that must be initialized.
buffer = (uint64_t*)cxplat_allocate_with_tag(CxPlatNonPagedPoolNx, 8, TEST_TAG, true);
REQUIRE(buffer != nullptr);
REQUIRE(*buffer == 0);
*buffer = 42;
cxplat_free(buffer);
}

TEST_CASE("reallocate unaligned", "[memory]")
{
// Try an allocation that need not be cache aligned.
uint64_t* original_buffer = (uint64_t*)cxplat_allocate_with_tag(CxPlatNonPagedPoolNx, 8, TEST_TAG, true);
REQUIRE(original_buffer != nullptr);

uint64_t* new_buffer = (uint64_t*)cxplat_reallocate(original_buffer, 8, 16);
REQUIRE(new_buffer != nullptr);
REQUIRE(new_buffer[1] == 0);

cxplat_free(new_buffer);
}

TEST_CASE("reallocate aligned", "[memory]")
{
// Try an allocation that must be cache aligned.
uint64_t* original_buffer = (uint64_t*)cxplat_allocate_with_tag(CxPlatNonPagedPoolNxCacheAligned, 8, TEST_TAG, true);
REQUIRE(original_buffer != nullptr);

uint64_t* new_buffer = (uint64_t*)cxplat_reallocate(original_buffer, 8, 16);
REQUIRE(new_buffer != nullptr);
REQUIRE((((uintptr_t)new_buffer) % 64) == 0);
REQUIRE(new_buffer[1] == 0);

cxplat_free(new_buffer);
}

TEST_CASE("cxplat_free null", "[memory]") { cxplat_free(nullptr); }

TEST_CASE("cxplat_duplicate_string", "[memory]")
{
char* string = cxplat_duplicate_string("test");
REQUIRE(string != nullptr);
REQUIRE(strcmp(string, "test") == 0);

cxplat_free(string);
}

TEST_CASE("cxplat_duplicate_utf8_string", "[memory]")
{
const char string[] = "test";
cxplat_utf8_string_t source = CXPLAT_UTF8_STRING_FROM_CONST_STRING(string);
REQUIRE(source.length == strlen(string));

cxplat_utf8_string_t destination;
cxplat_status_t status = cxplat_duplicate_utf8_string(&destination, &source);
REQUIRE(status == CXPLAT_STATUS_SUCCESS);
REQUIRE(destination.length == source.length);
REQUIRE(memcmp(destination.value, source.value, source.length) == 0);

cxplat_utf8_string_free(&destination);
}
151 changes: 151 additions & 0 deletions cxplat/cxplat_test/cxplat_test.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\packages\CatchOrg.Catch.2.8.0\build\native\CatchOrg.Catch.props" Condition="Exists('..\..\packages\CatchOrg.Catch.2.8.0\build\native\CatchOrg.Catch.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{e356324b-74bb-4123-9fbe-dd8b8ed8658a}</ProjectGuid>
<RootNamespace>cxplattest</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>CMAKE_NUGET;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)external\catch2\src;$(SolutionDir)external\catch2\build\generated-includes;$(SolutionDir)cxplat\inc;$(SolutionDir)cxplat\inc\winuser;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>CMAKE_NUGET;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)external\catch2\src;$(SolutionDir)external\catch2\build\generated-includes;$(SolutionDir)cxplat\inc;$(SolutionDir)cxplat\inc\winuser;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="cxplat_memory_test.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\src\cxplat_winuser\cxplat_winuser.vcxproj">
<Project>{f2ca70ab-af9a-47d1-9da9-94d5ab573ac2}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\CatchOrg.Catch.2.8.0\build\native\CatchOrg.Catch.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\CatchOrg.Catch.2.8.0\build\native\CatchOrg.Catch.props'))" />
</Target>
</Project>
25 changes: 25 additions & 0 deletions cxplat/cxplat_test/cxplat_test.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="cxplat_memory_test.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>
4 changes: 4 additions & 0 deletions cxplat/cxplat_test/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CatchOrg.Catch" version="2.8.0" targetFramework="native" />
</packages>
21 changes: 21 additions & 0 deletions cxplat/inc/cxplat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT
#pragma once

#include "cxplat_fault_injection.h"
#include "cxplat_memory.h"

#ifdef __cplusplus
extern "C"
{
#endif
Comment on lines +8 to +11
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To simplify this stuff, we can define EXTERN_C (or EXTERN_C_START) and EXTERN_C_END in cxplat_common.h for this. It would reduce the duplication and line count a bit. It would also hide the { and } to eliminate any visible/explicit need to tab things over.

Copy link
Contributor Author

@dthaler dthaler Aug 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed #84


cxplat_status_t
cxplat_initialize();
Comment on lines +13 to +14
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind not having the spaces before all these lines? IMHO, it's a lot of wasted space.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think clang-format did it, the formatting isn't supposed to be manual.
We can see if there's a config option to do what you want.


void
cxplat_cleanup();

#ifdef __cplusplus
};
#endif
Loading