From 0ed34ae644285d0df6e8105dd4b0ba836ab7cbe5 Mon Sep 17 00:00:00 2001 From: Jon Wiswall Date: Sun, 25 May 2025 16:56:44 -0700 Subject: [PATCH] Add support for tracelogging of string types --- CMakePresets.json | 29 +++++++++-------- include/wil/stl.h | 71 +++++++++++++++++++++++++++++++++++++++++ scripts/call-vcvars.cmd | 20 +++++++++--- scripts/runtests.cmd | 8 +++-- tests/StlTests.cpp | 63 ++++++++++++++++++++++++++++++++++++ 5 files changed, 170 insertions(+), 21 deletions(-) diff --git a/CMakePresets.json b/CMakePresets.json index 61f23932..836f5905 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -14,6 +14,7 @@ "installDir": "${sourceDir}/build/install/${presetName}", "toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", "cacheVariables": { + "WIL_ENABLE_ASAN": true, "CMAKE_CONFIGURATION_TYPES": "Debug;RelWithDebInfo;Release;MinSizeRel", "CMAKE_CXX_COMPILER": "cl", "CMAKE_C_COMPILER": "cl" @@ -29,9 +30,19 @@ } }, "cacheVariables": { + "WIL_ENABLE_ASAN": false, "CMAKE_CXX_COMPILER": "clang-cl", "CMAKE_C_COMPILER": "clang-cl" } + }, + { + "name": "clang-release", + "inherits": "clang", + "hidden": false, + "cacheVariables": { + "WIL_ENABLE_ASAN": true, + "WIL_ENABLE_UBSAN": true + } } ], "buildPresets": [ @@ -39,19 +50,13 @@ "name": "msvc-debug", "displayName": "MSVC Debug", "configurePreset": "msvc", - "configuration": "Debug", - "cacheVariables": { - "WIL_ENABLE_ASAN": true - } + "configuration": "Debug" }, { "name": "msvc-release", "displayName": "MSVC Release (debuggable)", "configurePreset": "msvc", - "configuration": "RelWithDebInfo", - "cacheVariables": { - "WIL_ENABLE_ASAN": true - } + "configuration": "RelWithDebInfo" }, { "name": "clang-debug", @@ -62,12 +67,8 @@ { "name": "clang-release", "displayName": "clang Release (debuggable)", - "configurePreset": "clang", - "configuration": "RelWithDebInfo", - "cacheVariables": { - "WIL_ENABLE_ASAN": true, - "WIL_ENABLE_UBSAN": true - } + "configurePreset": "clang-release", + "configuration": "RelWithDebInfo" } ], "testPresets": [ diff --git a/include/wil/stl.h b/include/wil/stl.h index 9e3dd437..5d9b7193 100644 --- a/include/wil/stl.h +++ b/include/wil/stl.h @@ -19,6 +19,7 @@ #include #include #include +#include #if (__WI_LIBCPP_STD_VER >= 17) && WI_HAS_INCLUDE(, 1) // Assume present if C++17 #include #endif @@ -266,6 +267,76 @@ struct std::formatter, TChar> : std::formatter= 201606L + +template +struct _tlgWrapBufferStlContainer +{ + static const unsigned DataDescCount = 2; + + TContainer const& view; + + __forceinline explicit _tlgWrapBufferStlContainer(_In_ TContainer const& ref) : view(ref) + { + } + + __forceinline void* Fill(_Out_writes_(DataDescCount) EVENT_DATA_DESCRIPTOR* pDesc) const + { + EventDataDescCreate(&pDesc[0], &pDesc[1].Size, 2); + EventDataDescCreate(&pDesc[1], view.data(), static_cast(view.size() * sizeof(*view.data()))); + return pDesc; + } +}; + +template +struct _tlgTypeMapStlString +{ + typedef UINT8 _tlgTypeType0; + typedef UINT16 _tlgTypeType1; + static bool const _tlgIsSimple = false; + static TlgIn_t const _tlgViewIn = wistd::is_same_v ? TlgInCOUNTEDANSISTRING : TlgInCOUNTEDSTRING; + static _tlgTypeType0 const _tlgType0 = _tlgViewIn | 0x0000; + static _tlgTypeType1 const _tlgType1 = _tlgViewIn | 0x8080; +}; + +template +struct _tlgTypeMapBase> : _tlgTypeMapStlString +{ +}; + +template +TLG_INLINE auto _tlg_CALL _tlgWrapAuto(std::basic_string_view const& value) +{ + return _tlgWrapBufferStlContainer>(value); +} + +template +struct _tlgTypeMapBase> : _tlgTypeMapStlString +{ +}; + +template +TLG_INLINE auto _tlg_CALL _tlgWrapAuto(std::basic_string const& value) +{ + return _tlgWrapBufferStlContainer>(value); +} + +template +struct _tlgTypeMapBase> : _tlgTypeMapStlString +{ +}; + +template +TLG_INLINE auto _tlg_CALL _tlgWrapAuto(wil::basic_zstring_view const& value) +{ + return _tlgWrapBufferStlContainer>(value); +} + +#define TraceLoggingStringView(pValue, ...) _tlgArgAuto(static_cast(pValue), __VA_ARGS__) +#define TraceLoggingWideStringView(pValue, ...) _tlgArgAuto(static_cast(pValue), __VA_ARGS__) + +#endif // __cpp_lib_string_view >= 201606L + #endif // WIL_ENABLE_EXCEPTIONS #endif // __WIL_STL_INCLUDED diff --git a/scripts/call-vcvars.cmd b/scripts/call-vcvars.cmd index 924276b3..75def32f 100644 --- a/scripts/call-vcvars.cmd +++ b/scripts/call-vcvars.cmd @@ -2,10 +2,20 @@ :: NOTE: Intentionally not specifying 'setlocal' as we want the side-effects of calling 'vcvars' to affect the caller -:: NOTE: This is primarily intended to be used by the build pipelines, hence the hard-coded paths, and might not be -:: generally useful. The following check is intended to help diagnose such possible issues -if NOT EXIST "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" ( - echo ERROR: Could not locate 'vcvars' batch file. This script is intended to be run from a build machine & exit /B 1 +:: Use vswhere.exe to find the Visual Studio installation path +for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do ( + set VS_INSTALL_PATH=%%i +) + +if "%VS_INSTALL_PATH%"=="" ( + echo ERROR: Could not locate Visual Studio installation with required C++ tools using vswhere.exe + exit /B 1 +) + +set VCVARS_PATH=%VS_INSTALL_PATH%\VC\Auxiliary\Build\vcvarsall.bat +if NOT EXIST "%VCVARS_PATH%" ( + echo ERROR: Could not locate vcvarsall.bat at %VCVARS_PATH% + exit /B 1 ) set ARCH=%1 @@ -14,4 +24,4 @@ if /I "%ARCH%"=="x86" ( set ARCH=x64_x86 ) -call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" %ARCH% +call "%VCVARS_PATH%" %ARCH% diff --git a/scripts/runtests.cmd b/scripts/runtests.cmd index 908c239f..8c866df2 100644 --- a/scripts/runtests.cmd +++ b/scripts/runtests.cmd @@ -40,7 +40,7 @@ if not exist %BUILD_DIR% ( goto :eof ) :: MSVC does not currently ship a version of the x64 ASan DLL that can be run on an arm64 host. MSVC _does_ ship a lib :: so we _can_ build the ASan tests, which is at least something. For now we're going to handle this limitation here and :: avoid running the ASan test in this specific scenario -set RUN_ASAN_TEST=1 +if not %RUN_ASAN_TEST%=='' set RUN_ASAN_TEST=1 if %PROCESSOR_ARCHITECTURE%==ARM64 ( if %2==x64 set RUN_ASAN_TEST=0 ) @@ -69,11 +69,15 @@ if %ERRORLEVEL% NEQ 0 ( goto :execute_tests_done ) :execute_tests_done set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% NEQ 0 ( + echo Tests failed in %BUILD_DIR% with exit code %EXIT_CODE% + goto :eof +) popd exit /B %EXIT_CODE% :execute_test if not exist tests\%1\%2 ( goto :eof ) -echo Running %1 tests... +echo Running tests\%1\%2 %TEST_ARGS% tests\%1\%2 %TEST_ARGS% goto :eof diff --git a/tests/StlTests.cpp b/tests/StlTests.cpp index 4fbdfc02..e0639fb0 100644 --- a/tests/StlTests.cpp +++ b/tests/StlTests.cpp @@ -244,4 +244,67 @@ TEST_CASE("StlTests::TestZWStringView", "[stl][zstring_view]") REQUIRE(wil::zwstring_view(fake_path) == L"hello"); } +/* bd2bf191-ac1a-4732-b563-bb3e3006f617 */ +TRACELOGGING_DEFINE_PROVIDER( // defines g_hProvider + g_tlgProvider, // Name of the provider variable + "MyProvider", // Human-readable name of the provider + (0xbd2bf191, 0xac1a, 0x4732, 0xb5, 0x63, 0xbb, 0x3e, 0x30, 0x06, 0xf6, 0x17)); // Provider GUID + +TEST_CASE("TraceLogging for Views", "[tracelogging]") +{ +#ifdef WIL_ENABLE_EXCEPTIONS + std::string_view sv = "kittens"; + std::wstring_view wsv = L"kittens"; + std::string s = "puppies"; + std::wstring ws = L"puppies"; + wil::zstring_view zv = "hamsters"; + wil::zwstring_view zwv = L"hamsters"; + + std::string_view const& rsv = sv; + std::wstring_view const& rwsv = wsv; + wil::zstring_view const& rzv = zv; + wil::zwstring_view const& rzwv = zwv; + + TraceLoggingRegister(g_tlgProvider); + + TraceLoggingWrite( + g_tlgProvider, + "Hello", + TraceLoggingStringView(sv, "sv"), + TraceLoggingWideStringView(wsv, "wsv"), + TraceLoggingStringView(s, "s"), + TraceLoggingWideStringView(ws, "ws"), + TraceLoggingStringView(zv, "zv"), + TraceLoggingWideStringView(zwv, "zwv")); + + TraceLoggingWrite( + g_tlgProvider, + "There", + TraceLoggingValue(sv, "sv"), + TraceLoggingValue(wsv, "wsv"), + TraceLoggingValue(s, "s"), + TraceLoggingValue(ws, "ws"), + TraceLoggingValue(zv, "zv"), + TraceLoggingValue(zwv, "zwv")); + + TraceLoggingWrite( + g_tlgProvider, + "HelloRefs", + TraceLoggingStringView(rsv, "sv"), + TraceLoggingWideStringView(rwsv, "wsv"), + TraceLoggingStringView(rzv, "zv"), + TraceLoggingWideStringView(rzwv, "zwv")); + + TraceLoggingWrite( + g_tlgProvider, + "ThereRefs", + TraceLoggingValue(rsv, "sv"), + TraceLoggingValue(rwsv, "wsv"), + TraceLoggingValue(rzv, "s"), + TraceLoggingValue(rzwv, "ws")); + + TraceLoggingUnregister(g_tlgProvider); +#endif +} + #endif