diff options
53 files changed, 1048 insertions, 2003 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d42deb9c2..af69a2a206 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,6 @@ endif (WIN32) set(CLR_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(VM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/vm) set(GENERATED_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/src/inc) -set(GENERATED_EVENTING_DIR ${CMAKE_CURRENT_BINARY_DIR}/eventing) set(VERSION_FILE_PATH "${CMAKE_BINARY_DIR}/version.cpp") set(CORECLR_SET_RPATH ON) @@ -28,7 +28,7 @@ set __ThisScriptDir="%~dp0" if defined VisualStudioVersion ( if not defined __VSVersion echo %__MsgPrefix%Detected Visual Studio %VisualStudioVersion% developer command ^prompt environment goto :Run -) +) echo %__MsgPrefix%Searching ^for Visual Studio 2017 or 2015 installation set _VSWHERE="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" @@ -294,16 +294,6 @@ if %__EnforcePgo%==1 ( ) ) -REM Determine if this is a cross-arch build - -if /i "%__BuildArch%"=="arm64" ( - set __DoCrossArchBuild=1 - ) - -if /i "%__BuildArch%"=="arm" ( - set __DoCrossArchBuild=1 - ) - :: Set the remaining variables based upon the determined build configuration set "__BinDir=%__RootBinDir%\Product\%__BuildOS%.%__BuildArch%.%__BuildType%" set "__IntermediatesDir=%__RootBinDir%\obj\%__BuildOS%.%__BuildArch%.%__BuildType%" @@ -392,38 +382,6 @@ for /f "tokens=*" %%s in ('%DotNetCli% msbuild "%OptDataProjectFilePath%" /t:Dum REM ========================================================================================= REM === -REM === Generate source files for eventing -REM === -REM ========================================================================================= - -REM Find python and set it to the variable PYTHON -echo import sys; print sys.executable | (python2.7 || python2 || py -2 || python) > %TEMP%\pythonlocation.txt 2> NUL -set /p PYTHON=<%TEMP%\pythonlocation.txt -if NOT DEFINED PYTHON ( - echo %__MsgPrefix%Error: Could not find a python 2.7 installation - exit /b 1 -) - -if /i "%__DoCrossArchBuild%"=="1" ( - set __IntermediatesIncDir=%__CrossCompIntermediatesDir%\src\inc - set __IntermediatesEventingDir=%__CrossCompIntermediatesDir%\eventing -) else ( - set __IntermediatesIncDir=%__IntermediatesDir%\src\inc - set __IntermediatesEventingDir=%__IntermediatesDir%\eventing -) - -echo Laying out dynamically generated files consumed by the build system -echo Laying out dynamically generated Event test files and etmdummy stub functions -%PYTHON% -B -Wall %__SourceDir%\scripts\genEventing.py --inc %__IntermediatesIncDir% --dummy %__IntermediatesIncDir%\etmdummy.h --man %__SourceDir%\vm\ClrEtwAll.man --nonextern || exit /b 1 - -echo Laying out dynamically generated EventPipe Implementation -%PYTHON% -B -Wall %__SourceDir%\scripts\genEventPipe.py --man %__SourceDir%\vm\ClrEtwAll.man --intermediate %__IntermediatesEventingDir%\eventpipe --nonextern || exit /b 1 - -echo Laying out ETW event logging interface -%PYTHON% -B -Wall %__SourceDir%\scripts\genEtwProvider.py --man %__SourceDir%\vm\ClrEtwAll.man --intermediate %__IntermediatesIncDir% --exc %__SourceDir%\vm\ClrEtwAllMeta.lst || exit /b 1 - -REM ========================================================================================= -REM === REM === Build the CLR VM REM === REM ========================================================================================= @@ -518,6 +476,14 @@ REM === Build Cross-Architecture Native Components (if applicable) REM === REM ========================================================================================= +if /i "%__BuildArch%"=="arm64" ( + set __DoCrossArchBuild=1 + ) + +if /i "%__BuildArch%"=="arm" ( + set __DoCrossArchBuild=1 + ) + if /i "%__DoCrossArchBuild%"=="1" ( REM Scope environment changes start { setlocal @@ -194,9 +194,28 @@ generate_event_logging_sources() fi # Event Logging Infrastructure - __GeneratedIntermediate="$__IntermediatesDir/eventing" - __GeneratedIntermediateEventProvider="$__GeneratedIntermediate/eventprovider" - __GeneratedIntermediateEventPipe="$__GeneratedIntermediate/eventpipe" + __GeneratedIntermediate="$__IntermediatesDir/Generated" + __GeneratedIntermediateEventProvider="$__GeneratedIntermediate/eventprovider_new" + __GeneratedIntermediateEventPipe="$__GeneratedIntermediate/eventpipe_new" + + if [[ -d "$__GeneratedIntermediateEventProvider" ]]; then + rm -rf "$__GeneratedIntermediateEventProvider" + fi + + if [[ -d "$__GeneratedIntermediateEventPipe" ]]; then + rm -rf "$__GeneratedIntermediateEventPipe" + fi + + if [[ ! -d "$__GeneratedIntermediate/eventprovider" ]]; then + mkdir -p "$__GeneratedIntermediate/eventprovider" + fi + + if [[ ! -d "$__GeneratedIntermediate/eventpipe" ]]; then + mkdir -p "$__GeneratedIntermediate/eventpipe" + fi + + mkdir -p "$__GeneratedIntermediateEventProvider" + mkdir -p "$__GeneratedIntermediateEventPipe" __PythonWarningFlags="-Wall" if [[ $__IgnoreWarnings == 0 ]]; then @@ -206,38 +225,54 @@ generate_event_logging_sources() if [[ $__SkipCoreCLR == 0 || $__ConfigureOnly == 1 ]]; then echo "Laying out dynamically generated files consumed by the build system " - echo "Laying out dynamically generated Event test files, etmdummy stub functions, and external linkages" - $PYTHON -B $__PythonWarningFlags "$__ProjectRoot/src/scripts/genEventing.py" --inc $__IntermediatesDir/src/inc --dummy $__IntermediatesDir/src/inc/etmdummy.h --man "$__ProjectRoot/src/vm/ClrEtwAll.man" --testdir "$__GeneratedIntermediateEventProvider/tests" + echo "Laying out dynamically generated Event Logging Test files" + $PYTHON -B $__PythonWarningFlags "$__ProjectRoot/src/scripts/genXplatEventing.py" --man "$__ProjectRoot/src/vm/ClrEtwAll.man" --exc "$__ProjectRoot/src/vm/ClrEtwAllMeta.lst" --testdir "$__GeneratedIntermediateEventProvider/tests" if [[ $? != 0 ]]; then exit fi - echo "Laying out dynamically generated EventPipe Implementation" - $PYTHON -B $__PythonWarningFlags "$__ProjectRoot/src/scripts/genEventPipe.py" --man "$__ProjectRoot/src/vm/ClrEtwAll.man" --intermediate "$__GeneratedIntermediateEventPipe" - - #determine the logging system case $__BuildOS in Linux|FreeBSD) - echo "Laying out dynamically generated Event Logging Implementation of Lttng" - $PYTHON -B $__PythonWarningFlags "$__ProjectRoot/src/scripts/genLttngProvider.py" --man "$__ProjectRoot/src/vm/ClrEtwAll.man" --intermediate "$__GeneratedIntermediateEventProvider" + echo "Laying out dynamically generated EventPipe Implementation" + $PYTHON -B $__PythonWarningFlags "$__ProjectRoot/src/scripts/genEventPipe.py" --man "$__ProjectRoot/src/vm/ClrEtwAll.man" --intermediate "$__GeneratedIntermediateEventPipe" --exc "$__ProjectRoot/src/vm/ClrEtwAllMeta.lst" if [[ $? != 0 ]]; then exit fi ;; *) - echo "Laying out dummy event logging provider" - $PYTHON -B $__PythonWarningFlags "$__ProjectRoot/src/scripts/genDummyProvider.py" --man "$__ProjectRoot/src/vm/ClrEtwAll.man" --intermediate "$__GeneratedIntermediateEventProvider" + ;; + esac + + #determine the logging system + case $__BuildOS in + Linux|FreeBSD) + echo "Laying out dynamically generated Event Logging Implementation of Lttng" + $PYTHON -B $__PythonWarningFlags "$__ProjectRoot/src/scripts/genXplatLttng.py" --man "$__ProjectRoot/src/vm/ClrEtwAll.man" --intermediate "$__GeneratedIntermediateEventProvider" if [[ $? != 0 ]]; then exit fi ;; + *) + ;; esac + fi - if [[ $__CrossBuild == 1 ]]; then - cp -r $__GeneratedIntermediate $__CrossCompIntermediatesDir - fi + echo "Cleaning the temp folder of dynamically generated Event Logging files" + $PYTHON -B $__PythonWarningFlags -c "import sys;sys.path.insert(0,\"$__ProjectRoot/src/scripts\"); from Utilities import *;UpdateDirectory(\"$__GeneratedIntermediate/eventprovider\",\"$__GeneratedIntermediateEventProvider\")" + if [[ $? != 0 ]]; then + exit + fi + + rm -rf "$__GeneratedIntermediateEventProvider" + + echo "Cleaning the temp folder of dynamically generated EventPipe files" + $PYTHON -B $__PythonWarningFlags -c "import sys;sys.path.insert(0,\"$__ProjectRoot/src/scripts\"); from Utilities import *;UpdateDirectory(\"$__GeneratedIntermediate/eventpipe\",\"$__GeneratedIntermediateEventPipe\")" + if [[ $? != 0 ]]; then + exit fi + + rm -rf "$__GeneratedIntermediateEventPipe" } build_native() diff --git a/clr.coreclr.props b/clr.coreclr.props index 98df021084..691365c76c 100644 --- a/clr.coreclr.props +++ b/clr.coreclr.props @@ -3,8 +3,6 @@ <FeatureEventTrace>true</FeatureEventTrace> <FeatureICastable>true</FeatureICastable> <FeatureManagedEtwChannels>true</FeatureManagedEtwChannels> - <FeatureManagedEtw>true</FeatureManagedEtw> - <FeaturePerfTracing>true</FeaturePerfTracing> <ProfilingSupportedBuild>true</ProfilingSupportedBuild> </PropertyGroup> @@ -23,6 +21,7 @@ <PropertyGroup Condition="'$(TargetsWindows)' == 'true'"> <FeatureArrayStubAsIL Condition="'$(TargetArch)' != 'i386'">true</FeatureArrayStubAsIL> <FeatureMulticastStubAsIL Condition="'$(TargetArch)' != 'i386'">true</FeatureMulticastStubAsIL> + <FeatureManagedEtw>true</FeatureManagedEtw> <FeatureStubsAsIL Condition="'$(TargetArch)' == 'arm64'">true</FeatureStubsAsIL> <FeatureUseLcid>true</FeatureUseLcid> <FeatureCominterop>true</FeatureCominterop> @@ -33,4 +32,9 @@ <FeatureAppX>true</FeatureAppX> <FeatureWin32Registry>true</FeatureWin32Registry> </PropertyGroup> -</Project>
\ No newline at end of file + + <PropertyGroup Condition="'$(TargetsLinux)' == 'true'"> + <FeatureManagedEtw>true</FeatureManagedEtw> + <FeaturePerfTracing>true</FeaturePerfTracing> + </PropertyGroup> +</Project> diff --git a/clr.defines.targets b/clr.defines.targets index 9189f6f203..b9f159eb0c 100644 --- a/clr.defines.targets +++ b/clr.defines.targets @@ -20,7 +20,6 @@ <DefineConstants Condition="'$(FeatureManagedEtwChannels)' == 'true'">$(DefineConstants);FEATURE_MANAGED_ETW_CHANNELS</DefineConstants> <DefineConstants Condition="'$(FeaturePal)' == 'true'">$(DefineConstants);FEATURE_PAL</DefineConstants> <DefineConstants Condition="'$(FeaturePerfTracing)' == 'true'">$(DefineConstants);FEATURE_PERFTRACING</DefineConstants> - <DefineConstants Condition="'$(FeatureEventTrace)' == 'true'">$(DefineConstants);FEATURE_EVENT_TRACE</DefineConstants> <DefineConstants Condition="'$(FeatureXplatEventSource)' == 'true'">$(DefineConstants);FEATURE_EVENTSOURCE_XPLAT</DefineConstants> <DefineConstants Condition="'$(FeatureUseLcid)' == 'true'">$(DefineConstants);FEATURE_USE_LCID</DefineConstants> <DefineConstants Condition="'$(FeatureWin32Registry)' == 'true'">$(DefineConstants);FEATURE_WIN32_REGISTRY</DefineConstants> diff --git a/clrdefinitions.cmake b/clrdefinitions.cmake index 4216e8ed20..5e12ca1e05 100644 --- a/clrdefinitions.cmake +++ b/clrdefinitions.cmake @@ -125,7 +125,6 @@ if(FEATURE_DBGIPC) endif(FEATURE_DBGIPC) if(FEATURE_EVENT_TRACE) add_definitions(-DFEATURE_EVENT_TRACE=1) - add_definitions(-DFEATURE_PERFTRACING=1) endif(FEATURE_EVENT_TRACE) if(FEATURE_GDBJIT) add_definitions(-DFEATURE_GDBJIT) @@ -139,6 +138,9 @@ endif(FEATURE_GDBJIT_LANGID_CS) if(FEATURE_GDBJIT_SYMTAB) add_definitions(-DFEATURE_GDBJIT_SYMTAB) endif(FEATURE_GDBJIT_SYMTAB) +if(CLR_CMAKE_PLATFORM_LINUX) + add_definitions(-DFEATURE_PERFTRACING) +endif(CLR_CMAKE_PLATFORM_LINUX) if(CLR_CMAKE_PLATFORM_UNIX) add_definitions(-DFEATURE_EVENTSOURCE_XPLAT=1) endif(CLR_CMAKE_PLATFORM_UNIX) diff --git a/clrfeatures.cmake b/clrfeatures.cmake index 367777a501..b4d7bad2dd 100644 --- a/clrfeatures.cmake +++ b/clrfeatures.cmake @@ -3,12 +3,22 @@ if(CLR_CMAKE_TARGET_TIZEN_LINUX) endif() if(NOT DEFINED FEATURE_EVENT_TRACE) - set(FEATURE_EVENT_TRACE 1) -endif(NOT DEFINED FEATURE_EVENT_TRACE) + if (WIN32) + set(FEATURE_EVENT_TRACE 1) + endif() -if(NOT DEFINED FEATURE_PERFTRACING AND FEATURE_EVENT_TRACE) - set(FEATURE_PERFTRACING 1) -endif(NOT DEFINED FEATURE_PERFTRACING AND FEATURE_EVENT_TRACE) + if(CLR_CMAKE_PLATFORM_LINUX) + if(CLR_CMAKE_TARGET_TIZEN_LINUX) + set(FEATURE_EVENT_TRACE 1) + elseif(CLR_CMAKE_TARGET_ARCH_AMD64) + set(FEATURE_EVENT_TRACE 1) + elseif(CLR_CMAKE_TARGET_ARCH_ARM) + set(FEATURE_EVENT_TRACE 1) + elseif(CLR_CMAKE_TARGET_ARCH_ARM64) + set(FEATURE_EVENT_TRACE 1) + endif() + endif(CLR_CMAKE_PLATFORM_LINUX) +endif(NOT DEFINED FEATURE_EVENT_TRACE) if(NOT DEFINED FEATURE_DBGIPC) if(CLR_CMAKE_PLATFORM_UNIX AND (NOT CLR_CMAKE_PLATFORM_ANDROID)) diff --git a/dependencies.props b/dependencies.props index de6beb33fa..33d491e5d0 100644 --- a/dependencies.props +++ b/dependencies.props @@ -38,7 +38,7 @@ <XunitPackageVersion>2.2.0-beta2-build3300</XunitPackageVersion> <XunitConsoleNetcorePackageVersion>1.0.2-prerelease-00177</XunitConsoleNetcorePackageVersion> <XunitPerformanceApiPackageVersion>1.0.0-beta-build0012</XunitPerformanceApiPackageVersion> - <MicrosoftDiagnosticsTracingTraceEventPackageVersion>2.0.2</MicrosoftDiagnosticsTracingTraceEventPackageVersion> + <MicrosoftDiagnosticsTracingTraceEventPackageVersion>1.0.3-alpha-experimental</MicrosoftDiagnosticsTracingTraceEventPackageVersion> <VCRuntimeVersion>1.2.0</VCRuntimeVersion> </PropertyGroup> diff --git a/functions.cmake b/functions.cmake index c2286839dd..15d0cd929c 100644 --- a/functions.cmake +++ b/functions.cmake @@ -44,11 +44,11 @@ endfunction(get_include_directories) # Build a list of include directories for consumption by the assembler function(get_include_directories_asm IncludeDirectories) get_directory_property(dirs INCLUDE_DIRECTORIES) - + if (CLR_CMAKE_PLATFORM_ARCH_ARM AND WIN32) list(APPEND INC_DIRECTORIES "-I ") endif() - + foreach(dir IN LISTS dirs) if (CLR_CMAKE_PLATFORM_ARCH_ARM AND WIN32) list(APPEND INC_DIRECTORIES ${dir};) @@ -141,7 +141,7 @@ function(strip_symbols targetName outputFilename) add_custom_command( TARGET ${targetName} POST_BUILD - VERBATIM + VERBATIM COMMAND ${DSYMUTIL} --flat --minimize ${strip_source_file} COMMAND ${STRIP} -S ${strip_source_file} COMMENT Stripping symbols from ${strip_source_file} into file ${strip_destination_file} @@ -152,7 +152,7 @@ function(strip_symbols targetName outputFilename) add_custom_command( TARGET ${targetName} POST_BUILD - VERBATIM + VERBATIM COMMAND ${OBJCOPY} --only-keep-debug ${strip_source_file} ${strip_destination_file} COMMAND ${OBJCOPY} --strip-debug ${strip_source_file} COMMAND ${OBJCOPY} --add-gnu-debuglink=${strip_destination_file} ${strip_source_file} @@ -166,30 +166,30 @@ function(strip_symbols targetName outputFilename) endfunction() function(install_clr targetName) - list(FIND CLR_CROSS_COMPONENTS_LIST ${targetName} INDEX) - if (NOT DEFINED CLR_CROSS_COMPONENTS_LIST OR NOT ${INDEX} EQUAL -1) - strip_symbols(${targetName} strip_destination_file) - # On the older version of cmake (2.8.12) used on Ubuntu 14.04 the TARGET_FILE - # generator expression doesn't work correctly returning the wrong path and on - # the newer cmake versions the LOCATION property isn't supported anymore. - if(CMAKE_VERSION VERSION_EQUAL 3.0 OR CMAKE_VERSION VERSION_GREATER 3.0) - set(install_source_file $<TARGET_FILE:${targetName}>) - else() - get_property(install_source_file TARGET ${targetName} PROPERTY LOCATION) - endif() - - install(PROGRAMS ${install_source_file} DESTINATION .) - if(WIN32) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${targetName}.pdb DESTINATION PDB) - else() - install(FILES ${strip_destination_file} DESTINATION .) - endif() + list(FIND CLR_CROSS_COMPONENTS_LIST ${targetName} INDEX) + if (NOT DEFINED CLR_CROSS_COMPONENTS_LIST OR NOT ${INDEX} EQUAL -1) + strip_symbols(${targetName} strip_destination_file) + # On the older version of cmake (2.8.12) used on Ubuntu 14.04 the TARGET_FILE + # generator expression doesn't work correctly returning the wrong path and on + # the newer cmake versions the LOCATION property isn't supported anymore. + if(CMAKE_VERSION VERSION_EQUAL 3.0 OR CMAKE_VERSION VERSION_GREATER 3.0) + set(install_source_file $<TARGET_FILE:${targetName}>) + else() + get_property(install_source_file TARGET ${targetName} PROPERTY LOCATION) + endif() + + install(PROGRAMS ${install_source_file} DESTINATION .) + if(WIN32) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${targetName}.pdb DESTINATION PDB) + else() + install(FILES ${strip_destination_file} DESTINATION .) + endif() if(CLR_CMAKE_PGO_INSTRUMENT) if(WIN32) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${targetName}.pgd DESTINATION PGD OPTIONAL) endif() endif() - endif() + endif() endfunction() # Disable PAX mprotect that would prevent JIT and other codegen in coreclr from working. @@ -217,11 +217,11 @@ function(_add_executable) else() add_executable(${ARGV}) endif(NOT WIN32) - list(FIND CLR_CROSS_COMPONENTS_LIST ${ARGV0} INDEX) - if (DEFINED CLR_CROSS_COMPONENTS_LIST AND ${INDEX} EQUAL -1) - set_target_properties(${ARGV0} PROPERTIES EXCLUDE_FROM_ALL 1) + list(FIND CLR_CROSS_COMPONENTS_LIST ${ARGV0} INDEX) + if (DEFINED CLR_CROSS_COMPONENTS_LIST AND ${INDEX} EQUAL -1) + set_target_properties(${ARGV0} PROPERTIES EXCLUDE_FROM_ALL 1) endif() -endfunction() +endfunction() function(_add_library) if(NOT WIN32) @@ -229,10 +229,10 @@ function(_add_library) else() add_library(${ARGV}) endif(NOT WIN32) - list(FIND CLR_CROSS_COMPONENTS_LIST ${ARGV0} INDEX) - if (DEFINED CLR_CROSS_COMPONENTS_LIST AND ${INDEX} EQUAL -1) - set_target_properties(${ARGV0} PROPERTIES EXCLUDE_FROM_ALL 1) - endif() + list(FIND CLR_CROSS_COMPONENTS_LIST ${ARGV0} INDEX) + if (DEFINED CLR_CROSS_COMPONENTS_LIST AND ${INDEX} EQUAL -1) + set_target_properties(${ARGV0} PROPERTIES EXCLUDE_FROM_ALL 1) + endif() endfunction() function(_install) @@ -263,8 +263,8 @@ function(verify_dependencies targetName errorMessage) TARGET ${targetName} POST_BUILD VERBATIM - COMMAND ${CMAKE_SOURCE_DIR}/verify-so.sh - $<TARGET_FILE:${targetName}> + COMMAND ${CMAKE_SOURCE_DIR}/verify-so.sh + $<TARGET_FILE:${targetName}> ${errorMessage} COMMENT "Verifying ${targetName} dependencies" ) @@ -273,8 +273,10 @@ endfunction() function(add_library_clr) _add_library(${ARGV}) + add_dependencies(${ARGV0} GeneratedEventingFiles) endfunction() function(add_executable_clr) _add_executable(${ARGV}) + add_dependencies(${ARGV0} GeneratedEventingFiles) endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0412226dfc..4c999b184d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,10 +10,70 @@ include_directories("classlibnative/cryptography") include_directories("classlibnative/inc") include_directories("${GENERATED_INCLUDE_DIR}") -if(WIN32 AND FEATURE_EVENT_TRACE) - include_directories("${GENERATED_INCLUDE_DIR}/etw") -endif(WIN32 AND FEATURE_EVENT_TRACE) +# The Following Logic is used to wire up Build dependencies for Generated files in Event Logging +# ClrEtwAll.man - Event Schema +# ClrEtwAllMeta.lst - MetaData list [provided to ensure Windows Desktop is not broken] +# genXplatEventing.py - has the core logic for parsing Event Schema +# genWinEtw.py - Uses genXplatEventing to generate Windows Specific ETW Files +# clretwallmain.h and etmdummy.h - Provides the Event Logging Functionality to the VM +# clrxplatevents.h - Used by clretwallmain.h on Non Windows platform +# ClrEtwAll.h - Used by clretwallmain.h on Windows +# ClrEtwAll.rc - Used by src/dlls/clretwrc/clretrw.rc on Windows + +set (ScriptGeneratedEventFiles + ${GENERATED_INCLUDE_DIR}/clretwallmain.h + ${GENERATED_INCLUDE_DIR}/etmdummy.h +) +set (GeneratedEventFiles) +if(WIN32) + set (GenEventFilesScript "${CLR_DIR}/src/scripts/genWinEtw.py") + set (GenEventArgs --eventheader "${GENERATED_INCLUDE_DIR}/ClrEtwAll.h" --macroheader "${GENERATED_INCLUDE_DIR}/clretwallmain.h") + + list (APPEND ScriptGeneratedEventFiles + ${GENERATED_INCLUDE_DIR}/ClrEtwAll.h + ) + + list (APPEND GeneratedEventFiles + ${GENERATED_INCLUDE_DIR}/ClrEtwAll.rc + ) + + add_custom_command( + COMMENT "Generating ETW resource Files" + COMMAND ${MC} -h ${GENERATED_INCLUDE_DIR} -r ${GENERATED_INCLUDE_DIR} -b -co -um -p FireEtw "${VM_DIR}/ClrEtwAll.man" + OUTPUT ${GENERATED_INCLUDE_DIR}/ClrEtwAll.h + DEPENDS "${VM_DIR}/ClrEtwAll.man" + ) +else() + set (GenEventFilesScript "${CLR_DIR}/src/scripts/genXplatEventing.py") + set (GenEventArgs --inc "${GENERATED_INCLUDE_DIR}") + + list (APPEND ScriptGeneratedEventFiles + ${GENERATED_INCLUDE_DIR}/clrxplatevents.h + ) +endif(WIN32) + +if(CLR_CMAKE_WARNINGS_ARE_ERRORS) + set(PYTHON_WARNING_FLAGS -Wall -Werror) +else() + set(PYTHON_WARNING_FLAGS -Wall) +endif(CLR_CMAKE_WARNINGS_ARE_ERRORS) + +add_custom_command( + COMMENT "Generating Eventing Files" + COMMAND ${PYTHON} -B ${PYTHON_WARNING_FLAGS} ${GenEventFilesScript} ${GenEventArgs} --man "${VM_DIR}/ClrEtwAll.man" --exc "${VM_DIR}/ClrEtwAllMeta.lst" --dummy "${GENERATED_INCLUDE_DIR}/etmdummy.h" + OUTPUT ${ScriptGeneratedEventFiles} + DEPENDS ${GenEventFilesScript} "${VM_DIR}/ClrEtwAll.man" "${VM_DIR}/ClrEtwAllMeta.lst" "${CLR_DIR}/src/scripts/genXplatEventing.py" +) + +list (APPEND GeneratedEventFiles + ${ScriptGeneratedEventFiles} +) + +add_custom_target( + GeneratedEventingFiles + DEPENDS ${GeneratedEventFiles} +) if(CLR_CMAKE_PLATFORM_UNIX) if(CLR_CMAKE_PLATFORM_LINUX) diff --git a/src/dlls/mscoree/coreclr/CMakeLists.txt b/src/dlls/mscoree/coreclr/CMakeLists.txt index 8043f7733a..8796cc16a5 100644 --- a/src/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/dlls/mscoree/coreclr/CMakeLists.txt @@ -4,8 +4,8 @@ if (WIN32) list(APPEND CLR_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/coreclr.def) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /ENTRY:CoreDllMain") - - # Incremental linking results in the linker inserting extra padding and routing function calls via thunks that can break the + + # Incremental linking results in the linker inserting extra padding and routing function calls via thunks that can break the # invariants (e.g. size of region between Jit_PatchedCodeLast-Jit_PatchCodeStart needs to fit in a page). set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /INCREMENTAL:NO") @@ -14,7 +14,7 @@ if (WIN32) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DELAYLOAD:api-ms-win-core-winrt-roparameterizediid-l1-1-0.dll") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DELAYLOAD:api-ms-win-ro-typeresolution-l1-1-0.dll") - + # No library groups for Win32 set(START_LIBRARY_GROUP) set(END_LIBRARY_GROUP) @@ -30,14 +30,14 @@ else() # of the utilcode will be used instead of the standard library delete operator. set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Xlinker -Bsymbolic -Xlinker -Bsymbolic-functions") - # The following linked options can be inserted into the linker libraries list to + # The following linked options can be inserted into the linker libraries list to # ensure proper resolving of circular references between a subset of the libraries. set(START_LIBRARY_GROUP -Wl,--start-group) set(END_LIBRARY_GROUP -Wl,--end-group) # These options are used to force every object to be included even if it's unused. set(START_WHOLE_ARCHIVE -Wl,--whole-archive) - set(END_WHOLE_ARCHIVE -Wl,--no-whole-archive) + set(END_WHOLE_ARCHIVE -Wl,--no-whole-archive) set(EXPORTS_LINKER_OPTION -Wl,--version-script=${EXPORTS_FILE}) endif(CMAKE_SYSTEM_NAME STREQUAL Linux OR CMAKE_SYSTEM_NAME STREQUAL FreeBSD OR CMAKE_SYSTEM_NAME STREQUAL NetBSD) @@ -74,7 +74,7 @@ if(FEATURE_MERGE_JIT_AND_ENGINE) endif(FEATURE_MERGE_JIT_AND_ENGINE) # IMPORTANT! Please do not rearrange the order of the libraries. The linker on Linux is -# order dependent and changing the order can result in undefined symbols in the shared +# order dependent and changing the order can result in undefined symbols in the shared # library. set(CORECLR_LIBRARIES utilcode @@ -119,34 +119,28 @@ if(WIN32) ) else() list(APPEND CORECLR_LIBRARIES - ${START_WHOLE_ARCHIVE} # force all PAL objects to be included so all exports are available + ${START_WHOLE_ARCHIVE} # force all PAL objects to be included so all exports are available coreclrpal - ${END_WHOLE_ARCHIVE} + tracepointprovider + ${END_WHOLE_ARCHIVE} mscorrc_debug palrt ) endif(WIN32) -if(FEATURE_PERFTRACING) +if(CLR_CMAKE_PLATFORM_UNIX AND FEATURE_EVENT_TRACE) + list(APPEND CORECLR_LIBRARIES + eventprovider + ) +endif(CLR_CMAKE_PLATFORM_UNIX AND FEATURE_EVENT_TRACE) + +if(CLR_CMAKE_PLATFORM_LINUX) list(APPEND CORECLR_LIBRARIES eventpipe - ) -endif(FEATURE_PERFTRACING) - -if(FEATURE_EVENT_TRACE) - if(CLR_CMAKE_PLATFORM_UNIX) - list(APPEND CORECLR_LIBRARIES - eventprovider # On Windows this library contains only macros - ) - endif(CLR_CMAKE_PLATFORM_UNIX) - if(CLR_CMAKE_PLATFORM_LINUX) - list(APPEND CORECLR_LIBRARIES - tracepointprovider - ) - endif(CLR_CMAKE_PLATFORM_LINUX) -endif(FEATURE_EVENT_TRACE) - -target_link_libraries(coreclr ${CORECLR_LIBRARIES}) + ) +endif(CLR_CMAKE_PLATFORM_LINUX) + +target_link_libraries(coreclr ${CORECLR_LIBRARIES}) if(WIN32) # Add dac table & debug resource to coreclr diff --git a/src/mscorlib/System.Private.CoreLib.csproj b/src/mscorlib/System.Private.CoreLib.csproj index 4c36439e85..fcb499bbcc 100644 --- a/src/mscorlib/System.Private.CoreLib.csproj +++ b/src/mscorlib/System.Private.CoreLib.csproj @@ -623,7 +623,7 @@ <Target Name="CDefineChecker" BeforeTargets="Build" Condition="'$(CheckCDefines)'=='true'"> <!-- Compiler Definition Verification --> <PropertyGroup> - <CMakeDefinitionSaveFile>$(IntermediateOutputPath)..\cmake.definitions</CMakeDefinitionSaveFile> + <CMakeDefinitionSaveFile>$(IntermediateOutputPath)\cmake.definitions</CMakeDefinitionSaveFile> </PropertyGroup> <Exec Command="python $(MSBuildThisFileDirectory)..\scripts\check-definitions.py "$(CMakeDefinitionSaveFile)" "$(DefineConstants)" "$(IgnoreDefineConstants)" " /> </Target> diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventPipe.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventPipe.cs index ac15202f93..539c60b55f 100644 --- a/src/mscorlib/src/System/Diagnostics/Eventing/EventPipe.cs +++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventPipe.cs @@ -15,12 +15,12 @@ namespace System.Diagnostics.Tracing [MarshalAs(UnmanagedType.LPWStr)] private string m_providerName; private UInt64 m_keywords; - private UInt32 m_loggingLevel; + private uint m_loggingLevel; internal EventPipeProviderConfiguration( string providerName, UInt64 keywords, - UInt32 loggingLevel) + uint loggingLevel) { if(string.IsNullOrEmpty(providerName)) { @@ -45,7 +45,7 @@ namespace System.Diagnostics.Tracing get { return m_keywords; } } - internal UInt32 LoggingLevel + internal uint LoggingLevel { get { return m_loggingLevel; } } @@ -54,13 +54,13 @@ namespace System.Diagnostics.Tracing internal sealed class EventPipeConfiguration { private string m_outputFile; - private UInt32 m_circularBufferSizeInMB; + private uint m_circularBufferSizeInMB; private List<EventPipeProviderConfiguration> m_providers; private TimeSpan m_minTimeBetweenSamples = TimeSpan.FromMilliseconds(1); internal EventPipeConfiguration( string outputFile, - UInt32 circularBufferSizeInMB) + uint circularBufferSizeInMB) { if(string.IsNullOrEmpty(outputFile)) { @@ -80,7 +80,7 @@ namespace System.Diagnostics.Tracing get { return m_outputFile; } } - internal UInt32 CircularBufferSizeInMB + internal uint CircularBufferSizeInMB { get { return m_circularBufferSizeInMB; } } @@ -90,13 +90,13 @@ namespace System.Diagnostics.Tracing get { return m_providers.ToArray(); } } - internal Int64 ProfilerSamplingRateInNanoseconds + internal long ProfilerSamplingRateInNanoseconds { // 100 nanoseconds == 1 tick. get { return m_minTimeBetweenSamples.Ticks * 100; } } - internal void EnableProvider(string providerName, UInt64 keywords, UInt32 loggingLevel) + internal void EnableProvider(string providerName, UInt64 keywords, uint loggingLevel) { m_providers.Add(new EventPipeProviderConfiguration( providerName, @@ -124,11 +124,6 @@ namespace System.Diagnostics.Tracing throw new ArgumentNullException(nameof(configuration)); } - if(configuration.Providers == null) - { - throw new ArgumentNullException(nameof(configuration.Providers)); - } - EventPipeProviderConfiguration[] providers = configuration.Providers; EventPipeInternal.Enable( @@ -151,7 +146,7 @@ namespace System.Diagnostics.Tracing // These PInvokes are used by the configuration APIs to interact with EventPipe. // [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] - internal static extern void Enable(string outputFile, UInt32 circularBufferSizeInMB, Int64 profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration[] providers, Int32 numProviders); + internal static extern void Enable(string outputFile, uint circularBufferSizeInMB, long profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration[] providers, int numProviders); [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] internal static extern void Disable(); @@ -163,15 +158,15 @@ namespace System.Diagnostics.Tracing internal static extern IntPtr CreateProvider(string providerName, UnsafeNativeMethods.ManifestEtw.EtwEnableCallback callbackFunc); [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] - internal static extern unsafe IntPtr DefineEvent(IntPtr provHandle, UInt32 eventID, Int64 keywords, UInt32 eventVersion, UInt32 level, void *pMetadata, UInt32 metadataLength); + internal static extern unsafe IntPtr DefineEvent(IntPtr provHandle, uint eventID, Int64 keywords, uint eventVersion, uint level, void *pMetadata, uint metadataLength); [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] internal static extern void DeleteProvider(IntPtr provHandle); [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] - internal static extern unsafe void WriteEvent(IntPtr eventHandle, UInt32 eventID, void* pData, UInt32 length, Guid* activityId, Guid* relatedActivityId); + internal static extern unsafe void WriteEvent(IntPtr eventHandle, uint eventID, void* pData, uint length, Guid* activityId, Guid* relatedActivityId); [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] - internal static extern unsafe void WriteEventData(IntPtr eventHandle, UInt32 eventID, EventProvider.EventData** pEventData, UInt32 dataCount, Guid* activityId, Guid* relatedActivityId); + internal static extern unsafe void WriteEventData(IntPtr eventHandle, uint eventID, EventProvider.EventData** pEventData, uint dataCount, Guid* activityId, Guid* relatedActivityId); } } diff --git a/src/pal/src/CMakeLists.txt b/src/pal/src/CMakeLists.txt index feb434cd3e..2ade61b3d6 100644 --- a/src/pal/src/CMakeLists.txt +++ b/src/pal/src/CMakeLists.txt @@ -239,14 +239,10 @@ add_library(coreclrpal ${PLATFORM_SOURCES} ) -# This builds in functionality to load LTTng tracepoints at runtime -# Needed when using LTTng to support event tracing on Linux -if(CLR_CMAKE_PLATFORM_LINUX) - add_library(tracepointprovider - STATIC - misc/tracepointprovider.cpp - ) -endif(CLR_CMAKE_PLATFORM_LINUX) +add_library(tracepointprovider + STATIC + misc/tracepointprovider.cpp +) if(CMAKE_SYSTEM_NAME STREQUAL Darwin) find_library(COREFOUNDATION CoreFoundation) @@ -380,7 +376,7 @@ endif(CMAKE_SYSTEM_NAME STREQUAL NetBSD) add_subdirectory(examples) if(FEATURE_EVENT_TRACE) - add_subdirectory(${GENERATED_EVENTING_DIR}/eventprovider ${CMAKE_CURRENT_BINARY_DIR}/eventprovider) + add_subdirectory($ENV{__IntermediatesDir}/Generated/eventprovider ${CMAKE_CURRENT_BINARY_DIR}/eventprovider) endif(FEATURE_EVENT_TRACE) # Install the static PAL library for VS diff --git a/src/pal/tests/palsuite/CMakeLists.txt b/src/pal/tests/palsuite/CMakeLists.txt index 6f36025d1a..0ea8969bab 100644 --- a/src/pal/tests/palsuite/CMakeLists.txt +++ b/src/pal/tests/palsuite/CMakeLists.txt @@ -31,7 +31,4 @@ add_subdirectory(miscellaneous) add_subdirectory(pal_specific) add_subdirectory(samples) add_subdirectory(threading) - -if(FEATURE_EVENT_TRACE) - add_subdirectory(${GENERATED_EVENTING_DIR}/eventprovider/tests ${CMAKE_CURRENT_BINARY_DIR}/eventprovider) -endif(FEATURE_EVENT_TRACE) +add_subdirectory($ENV{__IntermediatesDir}/Generated/eventprovider/tests ${CMAKE_CURRENT_BINARY_DIR}/eventprovider ) diff --git a/src/scripts/Utilities.py b/src/scripts/Utilities.py new file mode 100644 index 0000000000..c1ceec8e9f --- /dev/null +++ b/src/scripts/Utilities.py @@ -0,0 +1,49 @@ +from filecmp import dircmp +import shutil +import os + +def walk_recursively_and_update(dcmp): + #for different Files Copy from right to left + for name in dcmp.diff_files: + srcpath = dcmp.right + "/" + name + destpath = dcmp.left + "/" + name + print("Updating %s" % (destpath)) + if os.path.isfile(srcpath): + shutil.copyfile(srcpath, destpath) + else : + raise Exception("path: " + srcpath + "is neither a file or folder") + + #copy right only files + for name in dcmp.right_only: + srcpath = dcmp.right + "/" + name + destpath = dcmp.left + "/" + name + print("Updating %s" % (destpath)) + if os.path.isfile(srcpath): + shutil.copyfile(srcpath, destpath) + elif os.path.isdir(srcpath): + shutil.copytree(srcpath, destpath) + else : + raise Exception("path: " + srcpath + "is neither a file or folder") + + #delete left only files + for name in dcmp.left_only: + path = dcmp.left + "/" + name + print("Deleting %s" % (path)) + if os.path.isfile(path): + os.remove(path) + elif os.path.isdir(path): + shutil.rmtree(path) + else : + raise Exception("path: " + path + "is neither a file or folder") + + #call recursively + for sub_dcmp in dcmp.subdirs.values(): + walk_recursively_and_update(sub_dcmp) + +def UpdateDirectory(destpath,srcpath): + + print("Updating %s with %s" % (destpath,srcpath)) + if not os.path.exists(destpath): + os.makedirs(destpath) + dcmp = dircmp(destpath,srcpath) + walk_recursively_and_update(dcmp) diff --git a/src/scripts/check-definitions.py b/src/scripts/check-definitions.py index 4f1026d4ef..59b309a3e6 100644 --- a/src/scripts/check-definitions.py +++ b/src/scripts/check-definitions.py @@ -33,17 +33,18 @@ debug = 0 # For the native part, return the sorted definition array. def loadDefinitionFile(filename): result = [] - try: - with open(filename, 'r') as f: - for line in f: - line = line.strip() - if line: - result.append(line) - except IOError: - # If cmake was not used, this script won't work, and that's ok + f = open(filename, 'r') + except: sys.exit(0) + # if cmake was not used (because of skipnative or systems that do not use cmake), this script won't work. + + for line in f: + theLine = line.rstrip("\r\n").strip() + if (len(theLine) > 0): + result.append(theLine) + f.close() result = sorted(result) return result @@ -107,10 +108,9 @@ def getDiff(arrNative, arrManaged): def printPotentiallyCritical(arrDefinitions, referencedFilename, arrIgnore): - content = None - with open(referencedFilename, 'r') as f: - content = f.read() - + f = open(referencedFilename, 'r') + content = f.read() + f.close() for keyword in arrDefinitions: skip = 0 diff --git a/src/scripts/genDummyProvider.py b/src/scripts/genDummyProvider.py deleted file mode 100644 index 0704554263..0000000000 --- a/src/scripts/genDummyProvider.py +++ /dev/null @@ -1,211 +0,0 @@ -## -## Licensed to the .NET Foundation under one or more agreements. -## The .NET Foundation licenses this file to you under the MIT license. -## See the LICENSE file in the project root for more information. -## -## This script exists to create a dummy implementaion of the eventprovider -## interface from a manifest file -## -## The intended use if for platforms which support event pipe -## but do not have a an eventing platform to recieve report events - -import os -from genEventing import * -from utilities import open_for_update - -stdprolog_cpp=""" -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/****************************************************************** - -DO NOT MODIFY. AUTOGENERATED FILE. -This file is generated using the logic from <root>/src/scripts/genDummyProvider.py - -******************************************************************/ -""" -stdprolog_cmake=""" -# -# -#****************************************************************** - -#DO NOT MODIFY. AUTOGENERATED FILE. -#This file is generated using the logic from <root>/src/scripts/genDummyProvider.py - -#****************************************************************** -""" - -def trimProvName(name): - name = name.replace("Windows-",'') - name = name.replace("Microsoft-",'') - name = name.replace('-','_') - return name - -def escapeProvFilename(name): - name = name.replace('_','') - name = name.lower() - return name - -def generateDummyProvider(providerName, eventNodes, allTemplates, extern): - impl = [] - for eventNode in eventNodes: - eventName = eventNode.getAttribute('symbol') - templateName = eventNode.getAttribute('template') - - #generate EventXplatEnabled - if extern: impl.append('extern "C" ') - impl.append("BOOL EventXplatEnabled%s(){ return FALSE; }\n\n" % (eventName,)) - - #generate FireEtw functions - fnptype = [] - linefnptype = [] - if extern: fnptype.append('extern "C" ') - fnptype.append("ULONG FireEtXplat") - fnptype.append(eventName) - fnptype.append("(\n") - - - if templateName: - template = allTemplates[templateName] - else: - template = None - - if template: - fnSig = template.signature - for paramName in fnSig.paramlist: - fnparam = fnSig.getParam(paramName) - wintypeName = fnparam.winType - typewName = palDataTypeMapping[wintypeName] - winCount = fnparam.count - countw = palDataTypeMapping[winCount] - - if paramName in template.structs: - linefnptype.append("%sint %s_ElementSize,\n" % (lindent, paramName)) - - linefnptype.append(lindent) - linefnptype.append(typewName) - if countw != " ": - linefnptype.append(countw) - - linefnptype.append(" ") - linefnptype.append(fnparam.name) - linefnptype.append(",\n") - - if len(linefnptype) > 0 : - del linefnptype[-1] - - fnptype.extend(linefnptype) - fnptype.append(")\n{\n") - impl.extend(fnptype) - - #start of fn body - impl.append(" return ERROR_SUCCESS;\n") - impl.append("}\n\n") - - return ''.join(impl) - -def generateDummyFiles(etwmanifest, out_dirname, extern): - tree = DOM.parse(etwmanifest) - - #keep these relative - dummy_directory = "dummy" - dummyevntprovPre = os.path.join(dummy_directory, "eventprov") - - if not os.path.exists(out_dirname): - os.makedirs(out_dirname) - - if not os.path.exists(os.path.join(out_dirname, dummy_directory)): - os.makedirs(os.path.join(out_dirname, dummy_directory)) - - # Cmake - with open_for_update(os.path.join(out_dirname, "CMakeLists.txt")) as cmake: - cmake.write(stdprolog_cmake + "\n") - cmake.write("\ncmake_minimum_required(VERSION 2.8.12.2)\n") - if extern: cmake.write("\nproject(eventprovider)\n") - cmake.write(""" - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -if(FEATURE_PAL) - add_definitions(-DPAL_STDCPP_COMPAT=1) - include_directories(${COREPAL_SOURCE_DIR}/inc/rt) -endif(FEATURE_PAL) -include_directories(dummy) - -""") - if extern: cmake.write("add_library") - else: cmake.write("add_library_clr") - cmake.write("""(eventprovider - STATIC\n""") - - for providerNode in tree.getElementsByTagName('provider'): - providerName = trimProvName(providerNode.getAttribute('name')) - providerName_File = escapeProvFilename(providerName) - - cmake.write(' "%s%s.cpp"\n' % (dummyevntprovPre, providerName_File)) - - cmake.write(")") - if extern: cmake.write(""" - -# Install the static eventprovider library -install(TARGETS eventprovider DESTINATION lib) -""") - - # Dummy Instrumentation - for providerNode in tree.getElementsByTagName('provider'): - providerName = trimProvName(providerNode.getAttribute('name')) - providerName_File = escapeProvFilename(providerName) - - dummyevntprov = os.path.join(out_dirname, dummyevntprovPre + providerName_File + ".cpp") - - with open_for_update(dummyevntprov) as impl: - impl.write(stdprolog_cpp + "\n") - - impl.write(""" -#ifdef PLATFORM_UNIX -#include "pal_mstypes.h" -#include "pal_error.h" -#include "pal.h" -#define PAL_free free -#define PAL_realloc realloc -#include "pal/stackstring.hpp" -#endif - - -""") - - templateNodes = providerNode.getElementsByTagName('template') - eventNodes = providerNode.getElementsByTagName('event') - - allTemplates = parseTemplateNodes(templateNodes) - - #create the implementation of eventing functions : dummyeventprov*.cp - impl.write(generateDummyProvider(providerName, eventNodes, allTemplates, extern) + "\n") - -def main(argv): - - #parse the command line - parser = argparse.ArgumentParser(description="Generates the Code required to instrument LTTtng logging mechanism") - - required = parser.add_argument_group('required arguments') - required.add_argument('--man', type=str, required=True, - help='full path to manifest containig the description of events') - required.add_argument('--intermediate', type=str, required=True, - help='full path to eventprovider intermediate directory') - required.add_argument('--nonextern', action='store_true', - help='if specified, will generate files to be compiled into the CLR rather than externaly' ) - args, unknown = parser.parse_known_args(argv) - if unknown: - print('Unknown argument(s): ', ', '.join(unknown)) - return 1 - - sClrEtwAllMan = args.man - intermediate = args.intermediate - extern = not args.nonextern - - generateDummyFiles(sClrEtwAllMan, intermediate, extern) - -if __name__ == '__main__': - return_code = main(sys.argv[1:]) - sys.exit(return_code)
\ No newline at end of file diff --git a/src/scripts/genEtwProvider.py b/src/scripts/genEtwProvider.py deleted file mode 100644 index fc9d43800f..0000000000 --- a/src/scripts/genEtwProvider.py +++ /dev/null @@ -1,312 +0,0 @@ -## -## Licensed to the .NET Foundation under one or more agreements. -## The .NET Foundation licenses this file to you under the MIT license. -## See the LICENSE file in the project root for more information. -## -## This script generates the interface to ETW using MC.exe - -import os -from os import path -import shutil -import re -import sys -import argparse -import subprocess -import xml.dom.minidom as DOM -from genEventing import parseTemplateNodes -from utilities import open_for_update - -macroheader_filename = "etwmacros.h" -mcheader_filename = "ClrEtwAll.h" -clrxplat_filename = "clrxplatevents.h" -etw_dirname = "etw" -replacements = [ - (r"EventEnabled", "EventXplatEnabled"), - (r"\bPVOID\b", "void*") -] - -stdprolog_cpp=""" -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/****************************************************************** - -DO NOT MODIFY. AUTOGENERATED FILE. -This file is generated using the logic from <root>/src/scripts/genEtwProvider.py - -******************************************************************/ -""" -stdprolog_cmake=""" -# -# -#****************************************************************** - -#DO NOT MODIFY. AUTOGENERATED FILE. -#This file is generated using the logic from <root>/src/scripts/genEtwProvider.py - -#****************************************************************** -""" - -def genProviderInterface(manifest, intermediate): - provider_dirname = os.path.join(intermediate, etw_dirname) - - if not os.path.exists(provider_dirname): - os.makedirs(provider_dirname) - - cmd = ['mc.exe', '-h', provider_dirname, '-r', provider_dirname, '-b', '-co', '-um', '-p', 'FireEtXplat', manifest] - subprocess.check_call(cmd) - - header_text = None - with open(path.join(provider_dirname, mcheader_filename), 'r') as mcheader_file: - header_text = mcheader_file.read() - - for pattern, replacement in replacements: - header_text = re.sub(pattern, replacement, header_text) - - with open_for_update(path.join(provider_dirname, mcheader_filename)) as mcheader_file: - mcheader_file.write(header_text) - -def genCmake(intermediate): - # Top level Cmake - - with open_for_update(os.path.join(intermediate, "CMakeLists.txt")) as cmake_file: - cmake_file.write(stdprolog_cmake) - cmake_file.write(""" -project(eventprovider) - -cmake_minimum_required(VERSION 2.8.12.2) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -include_directories({0}) - -add_library_clr(eventprovider - STATIC - "{0}/{1}" - "{0}/{2}" -) - -#set_target_properties(eventprovider PROPERTIES LINKER_LANGUAGE Hxx) -""".format(etw_dirname, macroheader_filename, "ClrEtwAll.cpp")) - -def genXplatHeader(intermediate): - with open_for_update(path.join(intermediate, clrxplat_filename)) as header_file: - header_file.write(""" -#ifndef _CLR_XPLAT_EVENTS_H_ -#define _CLR_XPLAT_EVENTS_H_ - -#include "{0}/{1}" -#include "{0}/{2}" - -#endif //_CLR_XPLAT_EVENTS_H_ -""".format(etw_dirname, macroheader_filename, mcheader_filename)) - - -class EventExclusions: - def __init__(self): - self.nostack = set() - self.explicitstack = set() - self.noclrinstance = set() - -def parseExclusionList(exclusion_filename): - with open(exclusion_filename,'r') as ExclusionFile: - exclusionInfo = EventExclusions() - - for line in ExclusionFile: - line = line.strip() - - #remove comments - if not line or line.startswith('#'): - continue - - tokens = line.split(':') - #entries starting with nomac are ignored - if "nomac" in tokens: - continue - - if len(tokens) > 5: - raise Exception("Invalid Entry " + line + "in "+ exclusion_filename) - - eventProvider = tokens[2] - eventTask = tokens[1] - eventSymbol = tokens[4] - - if eventProvider == '': - eventProvider = "*" - if eventTask == '': - eventTask = "*" - if eventSymbol == '': - eventSymbol = "*" - entry = eventProvider + ":" + eventTask + ":" + eventSymbol - - if tokens[0].lower() == "nostack": - exclusionInfo.nostack.add(entry) - if tokens[0].lower() == "stack": - exclusionInfo.explicitstack.add(entry) - if tokens[0].lower() == "noclrinstanceid": - exclusionInfo.noclrinstance.add(entry) - - return exclusionInfo - -def getStackWalkBit(eventProvider, taskName, eventSymbol, stackSet): - for entry in stackSet: - tokens = entry.split(':') - - if len(tokens) != 3: - raise Exception("Error, possible error in the script which introduced the enrty "+ entry) - - eventCond = tokens[0] == eventProvider or tokens[0] == "*" - taskCond = tokens[1] == taskName or tokens[1] == "*" - symbolCond = tokens[2] == eventSymbol or tokens[2] == "*" - - if eventCond and taskCond and symbolCond: - return False - return True - -#Add the miscelaneous checks here -def checkConsistency(manifest, exclusion_filename): - tree = DOM.parse(manifest) - exclusionInfo = parseExclusionList(exclusion_filename) - for providerNode in tree.getElementsByTagName('provider'): - - stackSupportSpecified = {} - eventNodes = providerNode.getElementsByTagName('event') - templateNodes = providerNode.getElementsByTagName('template') - eventProvider = providerNode.getAttribute('name') - allTemplates = parseTemplateNodes(templateNodes) - - for eventNode in eventNodes: - taskName = eventNode.getAttribute('task') - eventSymbol = eventNode.getAttribute('symbol') - eventTemplate = eventNode.getAttribute('template') - eventValue = int(eventNode.getAttribute('value')) - clrInstanceBit = getStackWalkBit(eventProvider, taskName, eventSymbol, exclusionInfo.noclrinstance) - sLookupFieldName = "ClrInstanceID" - sLookupFieldType = "win:UInt16" - - if clrInstanceBit and allTemplates.get(eventTemplate): - # check for the event template and look for a field named ClrInstanceId of type win:UInt16 - fnParam = allTemplates[eventTemplate].getFnParam(sLookupFieldName) - - if not(fnParam and fnParam.winType == sLookupFieldType): - raise Exception(exclusion_filename + ":No " + sLookupFieldName + " field of type " + sLookupFieldType + " for event symbol " + eventSymbol) - - # If some versions of an event are on the nostack/stack lists, - # and some versions are not on either the nostack or stack list, - # then developer likely forgot to specify one of the versions - - eventStackBitFromNoStackList = getStackWalkBit(eventProvider, taskName, eventSymbol, exclusionInfo.nostack) - eventStackBitFromExplicitStackList = getStackWalkBit(eventProvider, taskName, eventSymbol, exclusionInfo.explicitstack) - sStackSpecificityError = exclusion_filename + ": Error processing event :" + eventSymbol + "(ID" + str(eventValue) + "): This file must contain either ALL versions of this event or NO versions of this event. Currently some, but not all, versions of this event are present\n" - - if not stackSupportSpecified.get(eventValue): - # Haven't checked this event before. Remember whether a preference is stated - if ( not eventStackBitFromNoStackList) or ( not eventStackBitFromExplicitStackList): - stackSupportSpecified[eventValue] = True - else: - stackSupportSpecified[eventValue] = False - else: - # We've checked this event before. - if stackSupportSpecified[eventValue]: - # When we last checked, a preference was previously specified, so it better be specified here - if eventStackBitFromNoStackList and eventStackBitFromExplicitStackList: - raise Exception(sStackSpecificityError) - else: - # When we last checked, a preference was not previously specified, so it better not be specified here - if ( not eventStackBitFromNoStackList) or ( not eventStackBitFromExplicitStackList): - raise Exception(sStackSpecificityError) - -def genEtwMacroHeader(manifest, exclusion_filename, intermediate): - provider_dirname = os.path.join(intermediate, etw_dirname) - - if not os.path.exists(provider_dirname): - os.makedirs(provider_dirname) - - tree = DOM.parse(manifest) - numOfProviders = len(tree.getElementsByTagName('provider')) - nMaxEventBytesPerProvider = 64 - - exclusionInfo = parseExclusionList(exclusion_filename) - - with open_for_update(os.path.join(provider_dirname, macroheader_filename)) as header_file: - header_file.write(stdprolog_cpp + "\n") - - header_file.write("#define NO_OF_ETW_PROVIDERS " + str(numOfProviders) + "\n") - header_file.write("#define MAX_BYTES_PER_ETW_PROVIDER " + str(nMaxEventBytesPerProvider) + "\n") - header_file.write("EXTERN_C __declspec(selectany) const BYTE etwStackSupportedEvents[NO_OF_ETW_PROVIDERS][MAX_BYTES_PER_ETW_PROVIDER] = \n{\n") - - for providerNode in tree.getElementsByTagName('provider'): - stackSupportedEvents = [0]*nMaxEventBytesPerProvider - eventNodes = providerNode.getElementsByTagName('event') - eventProvider = providerNode.getAttribute('name') - - for eventNode in eventNodes: - taskName = eventNode.getAttribute('task') - eventSymbol = eventNode.getAttribute('symbol') - eventTemplate = eventNode.getAttribute('template') - eventTemplate = eventNode.getAttribute('template') - eventValue = int(eventNode.getAttribute('value')) - eventIndex = eventValue // 8 - eventBitPositionInIndex = eventValue % 8 - - eventStackBitFromNoStackList = int(getStackWalkBit(eventProvider, taskName, eventSymbol, exclusionInfo.nostack)) - eventStackBitFromExplicitStackList = int(getStackWalkBit(eventProvider, taskName, eventSymbol, exclusionInfo.explicitstack)) - - # Shift those bits into position. For the explicit stack list, swap 0 and 1, so the eventValue* variables - # have 1 in the position iff we should issue a stack for the event. - eventValueUsingNoStackListByPosition = (eventStackBitFromNoStackList << eventBitPositionInIndex) - eventValueUsingExplicitStackListByPosition = ((1 - eventStackBitFromExplicitStackList) << eventBitPositionInIndex) - - # Commit the values to the in-memory array that we'll dump into the header file - stackSupportedEvents[eventIndex] = stackSupportedEvents[eventIndex] | eventValueUsingNoStackListByPosition; - if eventStackBitFromExplicitStackList == 0: - stackSupportedEvents[eventIndex] = stackSupportedEvents[eventIndex] | eventValueUsingExplicitStackListByPosition - - # print the bit array - line = [] - line.append("\t{") - for elem in stackSupportedEvents: - line.append(str(elem)) - line.append(", ") - - del line[-1] - line.append("},") - header_file.write(''.join(line) + "\n") - header_file.write("};\n") - -def genFiles(manifest, intermediate, exclusion_filename): - if not os.path.exists(intermediate): - os.makedirs(intermediate) - - genProviderInterface(manifest, intermediate) - genEtwMacroHeader(manifest, exclusion_filename, intermediate) - genXplatHeader(intermediate) - - -def main(argv): - #parse the command line - parser = argparse.ArgumentParser(description="Generates the Code required to instrument ETW logging mechanism") - - required = parser.add_argument_group('required arguments') - required.add_argument('--man', type=str, required=True, - help='full path to manifest containig the description of events') - required.add_argument('--exc', type=str, required=True, - help='full path to exclusion list') - required.add_argument('--intermediate', type=str, required=True, - help='full path to eventprovider intermediate directory') - args, unknown = parser.parse_known_args(argv) - if unknown: - print('Unknown argument(s): ', ', '.join(unknown)) - return 1 - - manifest = args.man - exclusion_filename = args.exc - intermediate = args.intermediate - - checkConsistency(manifest, exclusion_filename) - genFiles(manifest, intermediate, exclusion_filename) - -if __name__ == '__main__': - return_code = main(sys.argv[1:]) - sys.exit(return_code)
\ No newline at end of file diff --git a/src/scripts/genEventPipe.py b/src/scripts/genEventPipe.py index 96755ea459..8a970794c0 100644 --- a/src/scripts/genEventPipe.py +++ b/src/scripts/genEventPipe.py @@ -1,11 +1,10 @@ from __future__ import print_function -from genEventing import * -from genLttngProvider import * +from genXplatEventing import * +from genXplatLttng import * import os import xml.dom.minidom as DOM -from utilities import open_for_update -stdprolog_cpp = """// Licensed to the .NET Foundation under one or more agreements. +stdprolog = """// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -15,7 +14,6 @@ DO NOT MODIFY. AUTOGENERATED FILE. This file is generated using the logic from <root>/src/scripts/genEventPipe.py ******************************************************************/ - """ stdprolog_cmake = """# @@ -26,54 +24,11 @@ stdprolog_cmake = """# #This file is generated using the logic from <root>/src/scripts/genEventPipe.py #****************************************************************** - """ -eventpipe_dirname = "eventpipe" - -def generateMethodSignatureEnabled(eventName): - return "BOOL EventPipeEventEnabled%s()" % (eventName,) - -def generateMethodSignatureWrite(eventName, template, extern): - sig_pieces = [] - - if extern: sig_pieces.append('extern "C" ') - sig_pieces.append("ULONG EventPipeWriteEvent") - sig_pieces.append(eventName) - sig_pieces.append("(") - - if template: - sig_pieces.append("\n") - fnSig = template.signature - for paramName in fnSig.paramlist: - fnparam = fnSig.getParam(paramName) - wintypeName = fnparam.winType - typewName = palDataTypeMapping[wintypeName] - winCount = fnparam.count - countw = palDataTypeMapping[winCount] - - if paramName in template.structs: - sig_pieces.append( - "%sint %s_ElementSize,\n" % - (lindent, paramName)) - - sig_pieces.append(lindent) - sig_pieces.append(typewName) - if countw != " ": - sig_pieces.append(countw) - - sig_pieces.append(" ") - sig_pieces.append(fnparam.name) - sig_pieces.append(",\n") - - if len(sig_pieces) > 0: - del sig_pieces[-1] - - sig_pieces.append(")") - return ''.join(sig_pieces) def generateClrEventPipeWriteEventsImpl( - providerName, eventNodes, allTemplates, extern): + providerName, eventNodes, allTemplates, exclusionListFile): providerPrettyName = providerName.replace("Windows-", '') providerPrettyName = providerPrettyName.replace("Microsoft-", '') providerPrettyName = providerPrettyName.replace('-', '_') @@ -92,24 +47,54 @@ def generateClrEventPipeWriteEventsImpl( templateName = eventNode.getAttribute('template') # generate EventPipeEventEnabled function - eventEnabledImpl = generateMethodSignatureEnabled(eventName) + """ + eventEnabledImpl = """bool EventPipeEventEnabled%s() { return EventPipeEvent%s->IsEnabled(); } -""" % eventName +""" % (eventName, eventName) WriteEventImpl.append(eventEnabledImpl) # generate EventPipeWriteEvent function fnptype = [] + linefnptype = [] + fnptype.append("extern \"C\" ULONG EventPipeWriteEvent") + fnptype.append(eventName) + fnptype.append("(\n") if templateName: template = allTemplates[templateName] else: template = None - fnptype.append(generateMethodSignatureWrite(eventName, template, extern)) - fnptype.append("\n{\n") + if template: + fnSig = template.signature + for paramName in fnSig.paramlist: + fnparam = fnSig.getParam(paramName) + wintypeName = fnparam.winType + typewName = palDataTypeMapping[wintypeName] + winCount = fnparam.count + countw = palDataTypeMapping[winCount] + + if paramName in template.structs: + linefnptype.append( + "%sint %s_ElementSize,\n" % + (lindent, paramName)) + + linefnptype.append(lindent) + linefnptype.append(typewName) + if countw != " ": + linefnptype.append(countw) + + linefnptype.append(" ") + linefnptype.append(fnparam.name) + linefnptype.append(",\n") + + if len(linefnptype) > 0: + del linefnptype[-1] + + fnptype.extend(linefnptype) + fnptype.append(")\n{\n") checking = """ if (!EventPipeEventEnabled%s()) return ERROR_SUCCESS; """ % (eventName) @@ -130,9 +115,8 @@ def generateClrEventPipeWriteEventsImpl( WriteEventImpl.append("\n return ERROR_SUCCESS;\n}\n\n") # EventPipeProvider and EventPipeEvent initialization - if extern: WriteEventImpl.append('extern "C" ') WriteEventImpl.append( - "void Init" + + "extern \"C\" void Init" + providerPrettyName + "()\n{\n") WriteEventImpl.append( @@ -150,6 +134,7 @@ def generateClrEventPipeWriteEventsImpl( eventVersion = eventNode.getAttribute('version') eventLevel = eventNode.getAttribute('level') eventLevel = eventLevel.replace("win:", "EventPipeEventLevel::") + exclusionInfo = parseExclusionList(exclusionListFile) taskName = eventNode.getAttribute('task') initEvent = """ EventPipeEvent%s = EventPipeProvider%s->AddEvent(%s,%s,%s,%s); @@ -165,8 +150,8 @@ def generateWriteEventBody(template, providerName, eventName): header = """ char stackBuffer[%s]; char *buffer = stackBuffer; - size_t offset = 0; - size_t size = %s; + unsigned int offset = 0; + unsigned int size = %s; bool fixedBuffer = true; bool success = true; @@ -213,7 +198,7 @@ def generateWriteEventBody(template, providerName, eventName): }\n\n""" body = " EventPipe::WriteEvent(*EventPipeEvent" + \ - eventName + ", (BYTE *)buffer, (unsigned int)offset);\n" + eventName + ", (BYTE *)buffer, offset);\n" footer = """ if (!fixedBuffer) @@ -236,23 +221,20 @@ def generateEventKeywords(eventKeywords): return mask -def generateEventPipeCmakeFile(etwmanifest, eventpipe_directory, extern): +def generateEventPipeCmakeFile(etwmanifest, eventpipe_directory): tree = DOM.parse(etwmanifest) - with open_for_update(os.path.join(eventpipe_directory, "CMakeLists.txt")) as cmake_file: - cmake_file.write(stdprolog_cmake) - cmake_file.write("cmake_minimum_required(VERSION 2.8.12.2)\n") - if extern: cmake_file.write("\nproject(eventpipe)\n") - cmake_file.write(""" + with open(eventpipe_directory + "CMakeLists.txt", 'w') as topCmake: + topCmake.write(stdprolog_cmake + "\n") + topCmake.write("""cmake_minimum_required(VERSION 2.8.12.2) -set(CMAKE_INCLUDE_CURRENT_DIR ON) -include_directories(${CLR_DIR}/src/vm) + project(eventpipe) -""") - if extern: cmake_file.write("add_library") - else: cmake_file.write("add_library_clr") - cmake_file.write("""(eventpipe - STATIC\n""") + set(CMAKE_INCLUDE_CURRENT_DIR ON) + include_directories(${CLR_DIR}/src/vm) + + add_library(eventpipe + STATIC\n""") for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') @@ -262,41 +244,34 @@ include_directories(${CLR_DIR}/src/vm) providerName_File = providerName.replace('-', '') providerName_File = providerName_File.lower() - cmake_file.write(' "%s/%s.cpp"\n' % (eventpipe_dirname, providerName_File)) - cmake_file.write(' "%s/eventpipehelpers.cpp"\n)' % (eventpipe_dirname,)) - if extern: cmake_file.write(""" + topCmake.write(' "%s.cpp"\n' % (providerName_File)) + topCmake.write(' "eventpipehelpers.cpp"\n') + topCmake.write(""" ) + + add_dependencies(eventpipe GeneratedEventingFiles) + + # Install the static eventpipe library + install(TARGETS eventpipe DESTINATION lib) + """) + + topCmake.close() -# Install the static eventpipe library -install(TARGETS eventpipe DESTINATION lib) -""") -def generateEventPipeHelperFile(etwmanifest, eventpipe_directory, extern): - with open_for_update(os.path.join(eventpipe_directory, "eventpipehelpers.cpp")) as helper: - helper.write(stdprolog_cpp) +def generateEventPipeHelperFile(etwmanifest, eventpipe_directory): + with open(eventpipe_directory + "eventpipehelpers.cpp", 'w') as helper: + helper.write(stdprolog) helper.write(""" -#include "common.h" -#include <stdlib.h> -#include <string.h> - -#ifndef FEATURE_PAL -#include <windef.h> -#include <crtdbg.h> -#else -#include "pal.h" -#endif //FEATURE_PAL - -bool ResizeBuffer(char *&buffer, size_t& size, size_t currLen, size_t newSize, bool &fixedBuffer) +#include "stdlib.h" + +bool ResizeBuffer(char *&buffer, unsigned int& size, unsigned int currLen, unsigned int newSize, bool &fixedBuffer) { - newSize = (size_t)(newSize * 1.5); + newSize *= 1.5; _ASSERTE(newSize > size); // check for overflow if (newSize < 32) newSize = 32; - char *newBuffer = new (nothrow) char[newSize]; - - if (newBuffer == NULL) - return false; + char *newBuffer = new char[newSize]; memcpy(newBuffer, buffer, currLen); @@ -310,7 +285,7 @@ bool ResizeBuffer(char *&buffer, size_t& size, size_t currLen, size_t newSize, b return true; } -bool WriteToBuffer(const BYTE *src, size_t len, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) +bool WriteToBuffer(const BYTE *src, unsigned int len, char *&buffer, unsigned int& offset, unsigned int& size, bool &fixedBuffer) { if(!src) return true; if (offset + len > size) @@ -324,10 +299,10 @@ bool WriteToBuffer(const BYTE *src, size_t len, char *&buffer, size_t& offset, s return true; } -bool WriteToBuffer(PCWSTR str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) +bool WriteToBuffer(PCWSTR str, char *&buffer, unsigned int& offset, unsigned int& size, bool &fixedBuffer) { if(!str) return true; - size_t byteCount = (wcslen(str) + 1) * sizeof(*str); + unsigned int byteCount = (PAL_wcslen(str) + 1) * sizeof(*str); if (offset + byteCount > size) { @@ -340,10 +315,10 @@ bool WriteToBuffer(PCWSTR str, char *&buffer, size_t& offset, size_t& size, bool return true; } -bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) +bool WriteToBuffer(const char *str, char *&buffer, unsigned int& offset, unsigned int& size, bool &fixedBuffer) { if(!str) return true; - size_t len = strlen(str) + 1; + unsigned int len = strlen(str) + 1; if (offset + len > size) { if (!ResizeBuffer(buffer, size, offset, size + len, fixedBuffer)) @@ -364,18 +339,12 @@ bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, providerPrettyName = providerName.replace("Windows-", '') providerPrettyName = providerPrettyName.replace("Microsoft-", '') providerPrettyName = providerPrettyName.replace('-', '_') - if extern: helper.write( - 'extern "C" ' - ) helper.write( - "void Init" + + "extern \"C\" void Init" + providerPrettyName + "();\n\n") - if extern: helper.write( - 'extern "C" ' - ) - helper.write("void InitProvidersAndEvents()\n{\n") + helper.write("extern \"C\" void InitProvidersAndEvents()\n{\n") for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerPrettyName = providerName.replace("Windows-", '') @@ -386,20 +355,11 @@ bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, helper.close() + def generateEventPipeImplFiles( - etwmanifest, eventpipe_directory, extern): + etwmanifest, eventpipe_directory, exclusionListFile): tree = DOM.parse(etwmanifest) - - # Find the src directory starting with the assumption that - # A) It is named 'src' - # B) This script lives in it - src_dirname = os.path.dirname(__file__) - while os.path.basename(src_dirname) != "src": - src_dirname = os.path.dirname(src_dirname) - - if os.path.basename(src_dirname) == "": - raise IOError("Could not find the Core CLR 'src' directory") - + coreclrRoot = os.getcwd() for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') @@ -408,77 +368,74 @@ def generateEventPipeImplFiles( providerName_File = providerPrettyName.replace('-', '') providerName_File = providerName_File.lower() providerPrettyName = providerPrettyName.replace('-', '_') - eventpipefile = os.path.join(eventpipe_directory, providerName_File + ".cpp") - with open_for_update(eventpipefile) as eventpipeImpl: - eventpipeImpl.write(stdprolog_cpp) - - header = """ -#include "{root:s}/vm/common.h" -#include "{root:s}/vm/eventpipeprovider.h" -#include "{root:s}/vm/eventpipeevent.h" -#include "{root:s}/vm/eventpipe.h" + eventpipefile = eventpipe_directory + providerName_File + ".cpp" + eventpipeImpl = open(eventpipefile, 'w') + eventpipeImpl.write(stdprolog) -#if defined(FEATURE_PAL) -#define wcslen PAL_wcslen -#endif + header = """ +#include \"%s/src/vm/common.h\" +#include \"%s/src/vm/eventpipeprovider.h\" +#include \"%s/src/vm/eventpipeevent.h\" +#include \"%s/src/vm/eventpipe.h\" -bool ResizeBuffer(char *&buffer, size_t& size, size_t currLen, size_t newSize, bool &fixedBuffer); -bool WriteToBuffer(PCWSTR str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer); -bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer); -bool WriteToBuffer(const BYTE *src, size_t len, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer); +bool ResizeBuffer(char *&buffer, unsigned int& size, unsigned int currLen, unsigned int newSize, bool &fixedBuffer); +bool WriteToBuffer(PCWSTR str, char *&buffer, unsigned int& offset, unsigned int& size, bool &fixedBuffer); +bool WriteToBuffer(const char *str, char *&buffer, unsigned int& offset, unsigned int& size, bool &fixedBuffer); +bool WriteToBuffer(const BYTE *src, unsigned int len, char *&buffer, unsigned int& offset, unsigned int& size, bool &fixedBuffer); template <typename T> -bool WriteToBuffer(const T &value, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) -{{ +bool WriteToBuffer(const T &value, char *&buffer, unsigned int& offset, unsigned int& size, bool &fixedBuffer) +{ if (sizeof(T) + offset > size) - {{ - if (!ResizeBuffer(buffer, size, offset, size + sizeof(T), fixedBuffer)) - return false; - }} + { + if (!ResizeBuffer(buffer, size, offset, size + sizeof(T), fixedBuffer)) + return false; + } *(T *)(buffer + offset) = value; offset += sizeof(T); return true; -}} +} -""".format(root=src_dirname.replace('\\', '/')) +""" % (coreclrRoot, coreclrRoot, coreclrRoot, coreclrRoot) - eventpipeImpl.write(header) - eventpipeImpl.write( - "const WCHAR* %sName = W(\"%s\");\n" % ( - providerPrettyName, - providerName - ) + eventpipeImpl.write(header) + eventpipeImpl.write( + "const WCHAR* %sName = W(\"%s\");\n" % ( + providerPrettyName, + providerName ) - eventpipeImpl.write( - "EventPipeProvider *EventPipeProvider%s = nullptr;\n" % ( - providerPrettyName, - ) + ) + eventpipeImpl.write( + "EventPipeProvider *EventPipeProvider%s = nullptr;\n" % ( + providerPrettyName, ) - templateNodes = providerNode.getElementsByTagName('template') - allTemplates = parseTemplateNodes(templateNodes) - eventNodes = providerNode.getElementsByTagName('event') - eventpipeImpl.write( - generateClrEventPipeWriteEventsImpl( - providerName, - eventNodes, - allTemplates, - extern) + "\n") + ) + templateNodes = providerNode.getElementsByTagName('template') + allTemplates = parseTemplateNodes(templateNodes) + eventNodes = providerNode.getElementsByTagName('event') + eventpipeImpl.write( + generateClrEventPipeWriteEventsImpl( + providerName, + eventNodes, + allTemplates, + exclusionListFile) + "\n") + eventpipeImpl.close() def generateEventPipeFiles( - etwmanifest, intermediate, extern): - eventpipe_directory = os.path.join(intermediate, eventpipe_dirname) + etwmanifest, eventpipe_directory, exclusionListFile): + eventpipe_directory = eventpipe_directory + "/" tree = DOM.parse(etwmanifest) if not os.path.exists(eventpipe_directory): os.makedirs(eventpipe_directory) - # generate CMake file - generateEventPipeCmakeFile(etwmanifest, intermediate, extern) + # generate Cmake file + generateEventPipeCmakeFile(etwmanifest, eventpipe_directory) # generate helper file - generateEventPipeHelperFile(etwmanifest, eventpipe_directory, extern) + generateEventPipeHelperFile(etwmanifest, eventpipe_directory) # generate all keywords for keywordNode in tree.getElementsByTagName('keyword'): @@ -490,12 +447,12 @@ def generateEventPipeFiles( generateEventPipeImplFiles( etwmanifest, eventpipe_directory, - extern - ) + exclusionListFile) import argparse import sys + def main(argv): # parse the command line @@ -507,19 +464,19 @@ def main(argv): help='full path to manifest containig the description of events') required.add_argument('--intermediate', type=str, required=True, help='full path to eventprovider intermediate directory') - required.add_argument('--nonextern', action='store_true', - help='if specified, will generate files to be compiled into the CLR rather than extern' ) + required.add_argument('--exc', type=str, required=True, + help='full path to exclusion list') args, unknown = parser.parse_known_args(argv) if unknown: print('Unknown argument(s): ', ', '.join(unknown)) - return 1 + return const.UnknownArguments sClrEtwAllMan = args.man intermediate = args.intermediate - extern = not args.nonextern + exclusionListFile = args.exc - generateEventPipeFiles(sClrEtwAllMan, intermediate, extern) + generateEventPipeFiles(sClrEtwAllMan, intermediate, exclusionListFile) if __name__ == '__main__': return_code = main(sys.argv[1:]) - sys.exit(return_code)
\ No newline at end of file + sys.exit(return_code) diff --git a/src/scripts/genWinEtw.py b/src/scripts/genWinEtw.py new file mode 100644 index 0000000000..aa75f680cd --- /dev/null +++ b/src/scripts/genWinEtw.py @@ -0,0 +1,125 @@ + +## Licensed to the .NET Foundation under one or more agreements. +## The .NET Foundation licenses this file to you under the MIT license. +## See the LICENSE file in the project root for more information. +# + +import os +from genXplatEventing import * + +stdprolog=""" +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************** + +DO NOT MODIFY. AUTOGENERATED FILE. +This file is generated using the logic from <root>/src/scripts/genWinEtw.py + +******************************************************************/ + +""" +import argparse +import sys +import xml.dom.minidom as DOM + +def generateEtwMacroHeader(sClrEtwAllMan, sExcludeFile,macroHeader,inHeader): + tree = DOM.parse(sClrEtwAllMan) + numOfProviders = len(tree.getElementsByTagName('provider')) + nMaxEventBytesPerProvider = 64 + + exclusionInfo = parseExclusionList(sExcludeFile) + incDir = os.path.dirname(os.path.realpath(macroHeader)) + if not os.path.exists(incDir): + os.makedirs(incDir) + + outHeader = open(macroHeader,'w') + outHeader.write(stdprolog + "\n") + + outHeader.write("#include \"" + os.path.basename(inHeader) + '"\n') + outHeader.write("#define NO_OF_ETW_PROVIDERS " + str(numOfProviders) + "\n") + outHeader.write("#define MAX_BYTES_PER_ETW_PROVIDER " + str(nMaxEventBytesPerProvider) + "\n") + outHeader.write("EXTERN_C __declspec(selectany) const BYTE etwStackSupportedEvents[NO_OF_ETW_PROVIDERS][MAX_BYTES_PER_ETW_PROVIDER] = \n{\n") + + for providerNode in tree.getElementsByTagName('provider'): + stackSupportedEvents = [0]*nMaxEventBytesPerProvider + eventNodes = providerNode.getElementsByTagName('event') + eventProvider = providerNode.getAttribute('name') + + for eventNode in eventNodes: + taskName = eventNode.getAttribute('task') + eventSymbol = eventNode.getAttribute('symbol') + eventTemplate = eventNode.getAttribute('template') + eventTemplate = eventNode.getAttribute('template') + eventValue = int(eventNode.getAttribute('value')) + eventIndex = eventValue // 8 + eventBitPositionInIndex = eventValue % 8 + + eventStackBitFromNoStackList = int(getStackWalkBit(eventProvider, taskName, eventSymbol, exclusionInfo.nostack)) + eventStackBitFromExplicitStackList = int(getStackWalkBit(eventProvider, taskName, eventSymbol, exclusionInfo.explicitstack)) + + # Shift those bits into position. For the explicit stack list, swap 0 and 1, so the eventValue* variables + # have 1 in the position iff we should issue a stack for the event. + eventValueUsingNoStackListByPosition = (eventStackBitFromNoStackList << eventBitPositionInIndex) + eventValueUsingExplicitStackListByPosition = ((1 - eventStackBitFromExplicitStackList) << eventBitPositionInIndex) + + # Commit the values to the in-memory array that we'll dump into the header file + stackSupportedEvents[eventIndex] = stackSupportedEvents[eventIndex] | eventValueUsingNoStackListByPosition; + if eventStackBitFromExplicitStackList == 0: + stackSupportedEvents[eventIndex] = stackSupportedEvents[eventIndex] | eventValueUsingExplicitStackListByPosition + + # print the bit array + line = [] + line.append("\t{") + for elem in stackSupportedEvents: + line.append(str(elem)) + line.append(", ") + + del line[-1] + line.append("},") + outHeader.write(''.join(line) + "\n") + outHeader.write("};\n") + + outHeader.close() + + +def generateEtwFiles(sClrEtwAllMan, exclusionListFile, etmdummyHeader, macroHeader, inHeader): + + checkConsistency(sClrEtwAllMan, exclusionListFile) + generateEtmDummyHeader(sClrEtwAllMan, etmdummyHeader) + generateEtwMacroHeader(sClrEtwAllMan, exclusionListFile, macroHeader, inHeader) + +def main(argv): + + #parse the command line + parser = argparse.ArgumentParser(description="Generates the Code required to instrument LTTtng logging mechanism") + + required = parser.add_argument_group('required arguments') + required.add_argument('--man', type=str, required=True, + help='full path to manifest containig the description of events') + required.add_argument('--exc', type=str, required=True, + help='full path to exclusion list') + required.add_argument('--eventheader', type=str, required=True, + help='full path to the header file') + required.add_argument('--macroheader', type=str, required=True, + help='full path to the macro header file') + required.add_argument('--dummy', type=str, required=True, + help='full path to file that will have dummy definitions of FireEtw functions') + + args, unknown = parser.parse_known_args(argv) + if unknown: + print('Unknown argument(s): ', ', '.join(unknown)) + return const.UnknownArguments + + sClrEtwAllMan = args.man + exclusionListFile = args.exc + inHeader = args.eventheader + macroHeader = args.macroheader + etmdummyHeader = args.dummy + + generateEtwFiles(sClrEtwAllMan, exclusionListFile, etmdummyHeader, macroHeader, inHeader) + +if __name__ == '__main__': + return_code = main(sys.argv[1:]) + sys.exit(return_code) diff --git a/src/scripts/genEventing.py b/src/scripts/genXplatEventing.py index d6d6afbb90..4c9ce873b7 100644 --- a/src/scripts/genEventing.py +++ b/src/scripts/genXplatEventing.py @@ -6,7 +6,7 @@ # #USAGE: #Add Events: modify <root>src/vm/ClrEtwAll.man -#Look at the Code in <root>/src/scripts/genLttngProvider.py for using subroutines in this file +#Look at the Code in <root>/src/scripts/genXplatLttng.py for using subroutines in this file # # Python 2 compatibility @@ -14,7 +14,6 @@ from __future__ import print_function import os import xml.dom.minidom as DOM -from utilities import open_for_update stdprolog=""" // Licensed to the .NET Foundation under one or more agreements. @@ -24,7 +23,7 @@ stdprolog=""" /****************************************************************** DO NOT MODIFY. AUTOGENERATED FILE. -This file is generated using the logic from <root>/src/scripts/genEventing.py +This file is generated using the logic from <root>/src/scripts/genXplatEventing.py ******************************************************************/ """ @@ -35,7 +34,7 @@ stdprolog_cmake=""" #****************************************************************** #DO NOT MODIFY. AUTOGENERATED FILE. -#This file is generated using the logic from <root>/src/scripts/genEventing.py +#This file is generated using the logic from <root>/src/scripts/genXplatEventing.py #****************************************************************** """ @@ -261,7 +260,7 @@ def parseTemplateNodes(templateNodes): assert(countVarName in fnPrototypes.paramlist) if not countVarName: raise ValueError("Struct '%s' in template '%s' does not have an attribute count." % (structName, templateName)) - + names = [x.attributes['name'].value for x in structToBeMarshalled.getElementsByTagName("data")] types = [x.attributes['inType'].value for x in structToBeMarshalled.getElementsByTagName("data")] @@ -306,8 +305,8 @@ def generateClrallEvents(eventNodes,allTemplates): typewName = palDataTypeMapping[wintypeName] winCount = fnparam.count countw = palDataTypeMapping[winCount] - - + + if params in template.structs: fnptypeline.append("%sint %s_ElementSize,\n" % (lindent, params)) @@ -322,7 +321,7 @@ def generateClrallEvents(eventNodes,allTemplates): for params in fnSig.paramlist: fnparam = fnSig.getParam(params) - if params in template.structs: + if params in template.structs: line.append(fnparam.name + "_ElementSize") line.append(", ") @@ -350,23 +349,20 @@ def generateClrallEvents(eventNodes,allTemplates): return ''.join(clrallEvents) -def generateClrXplatEvents(eventNodes, allTemplates, extern): +def generateClrXplatEvents(eventNodes, allTemplates): clrallEvents = [] for eventNode in eventNodes: eventName = eventNode.getAttribute('symbol') templateName = eventNode.getAttribute('template') #generate EventEnabled - if extern: clrallEvents.append('extern "C" ') - clrallEvents.append("BOOL EventXplatEnabled") + clrallEvents.append("extern \"C\" BOOL EventXplatEnabled") clrallEvents.append(eventName) clrallEvents.append("();\n") - #generate FireEtw functions fnptype = [] fnptypeline = [] - if extern: fnptype.append('extern "C" ') - fnptype.append("ULONG FireEtXplat") + fnptype.append("extern \"C\" ULONG FireEtXplat") fnptype.append(eventName) fnptype.append("(\n") @@ -381,7 +377,7 @@ def generateClrXplatEvents(eventNodes, allTemplates, extern): winCount = fnparam.count countw = palDataTypeMapping[winCount] - + if params in template.structs: fnptypeline.append("%sint %s_ElementSize,\n" % (lindent, params)) @@ -402,7 +398,7 @@ def generateClrXplatEvents(eventNodes, allTemplates, extern): return ''.join(clrallEvents) -def generateClrEventPipeWriteEvents(eventNodes, allTemplates, extern): +def generateClrEventPipeWriteEvents(eventNodes, allTemplates): clrallEvents = [] for eventNode in eventNodes: eventName = eventNode.getAttribute('symbol') @@ -413,13 +409,11 @@ def generateClrEventPipeWriteEvents(eventNodes, allTemplates, extern): writeevent = [] fnptypeline = [] - if extern:eventenabled.append('extern "C" ') - eventenabled.append("BOOL EventPipeEventEnabled") + eventenabled.append("extern \"C\" bool EventPipeEventEnabled") eventenabled.append(eventName) eventenabled.append("();\n") - if extern: writeevent.append('extern "C" ') - writeevent.append("ULONG EventPipeWriteEvent") + writeevent.append("extern \"C\" ULONG EventPipeWriteEvent") writeevent.append(eventName) writeevent.append("(\n") @@ -560,70 +554,63 @@ def generateSanityTest(sClrEtwAllMan,testDir): cmake_file = testDir + "/CMakeLists.txt" test_cpp = "clralltestevents.cpp" testinfo = testDir + "/testinfo.dat" + Cmake_file = open(cmake_file,'w') + Test_cpp = open(testDir + "/" + test_cpp,'w') + Testinfo = open(testinfo,'w') #CMake File: - with open_for_update(cmake_file) as Cmake_file: - Cmake_file.write(stdprolog_cmake) - Cmake_file.write(""" -cmake_minimum_required(VERSION 2.8.12.2) -set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(SOURCES -""") - Cmake_file.write(test_cpp) - Cmake_file.write(""" - ) -include_directories(${GENERATED_INCLUDE_DIR}) - -if(FEATURE_PAL) - include_directories(${COREPAL_SOURCE_DIR}/inc/rt) -endif(FEATURE_PAL) - -add_executable(eventprovidertest - ${SOURCES} - ) -set(EVENT_PROVIDER_DEPENDENCIES "") -set(EVENT_PROVIDER_LINKER_OTPTIONS "") -if(FEATURE_EVENT_TRACE) - add_definitions(-DFEATURE_EVENT_TRACE=1) - list(APPEND EVENT_PROVIDER_DEPENDENCIES - eventprovider - ) - if(CLR_CMAKE_PLATFORM_LINUX) - list(APPEND EVENT_PROVIDER_DEPENDENCIES - coreclrtraceptprovider - ) - endif(CLR_CMAKE_PLATFORM_LINUX) - list(APPEND EVENT_PROVIDER_LINKER_OTPTIONS - ${EVENT_PROVIDER_DEPENDENCIES} + Cmake_file.write(stdprolog_cmake) + Cmake_file.write(""" + cmake_minimum_required(VERSION 2.8.12.2) + set(CMAKE_INCLUDE_CURRENT_DIR ON) + set(SOURCES + """) + Cmake_file.write(test_cpp) + Cmake_file.write(""" ) -endif(FEATURE_EVENT_TRACE) - -add_dependencies(eventprovidertest ${EVENT_PROVIDER_DEPENDENCIES} coreclrpal) -target_link_libraries(eventprovidertest - coreclrpal - ${EVENT_PROVIDER_LINKER_OTPTIONS} - ) -""") - - - with open_for_update(testinfo) as Testinfo: - Testinfo.write(""" -Copyright (c) Microsoft Corporation. All rights reserved. -# + include_directories(${GENERATED_INCLUDE_DIR}) + include_directories(${COREPAL_SOURCE_DIR}/inc/rt) -Version = 1.0 -Section = EventProvider -Function = EventProvider -Name = PAL test for FireEtW* and EventEnabled* functions -TYPE = DEFAULT -EXE1 = eventprovidertest -Description = This is a sanity test to check that there are no crashes in Xplat eventing -""") + add_executable(eventprovidertest + ${SOURCES} + ) + set(EVENT_PROVIDER_DEPENDENCIES "") + set(EVENT_PROVIDER_LINKER_OTPTIONS "") + if(FEATURE_EVENT_TRACE) + add_definitions(-DFEATURE_EVENT_TRACE=1) + list(APPEND EVENT_PROVIDER_DEPENDENCIES + coreclrtraceptprovider + eventprovider + ) + list(APPEND EVENT_PROVIDER_LINKER_OTPTIONS + ${EVENT_PROVIDER_DEPENDENCIES} + ) + + endif(FEATURE_EVENT_TRACE) + + add_dependencies(eventprovidertest ${EVENT_PROVIDER_DEPENDENCIES} coreclrpal) + target_link_libraries(eventprovidertest + coreclrpal + ${EVENT_PROVIDER_LINKER_OTPTIONS} + ) + """) + Testinfo.write(""" + Copyright (c) Microsoft Corporation. All rights reserved. + # + + Version = 1.0 + Section = EventProvider + Function = EventProvider + Name = PAL test for FireEtW* and EventEnabled* functions + TYPE = DEFAULT + EXE1 = eventprovidertest + Description + =This is a sanity test to check that there are no crashes in Xplat eventing + """) #Test.cpp - with open_for_update(testDir + "/" + test_cpp) as Test_cpp: - Test_cpp.write(stdprolog) - Test_cpp.write(""" + Test_cpp.write(stdprolog) + Test_cpp.write(""" /*===================================================================== ** ** Source: clralltestevents.cpp @@ -632,9 +619,7 @@ Description = This is a sanity test to check that there are no crashes in Xplat ** ** **===================================================================*/ -#if FEATURE_PAL #include <palsuite.h> -#endif //FEATURE_PAL #include <clrxplatevents.h> typedef struct _Struct1 { @@ -661,42 +646,39 @@ int win_Int32 = 12; BYTE* win_Binary =(BYTE*)var21 ; int __cdecl main(int argc, char **argv) { -#if defined(FEATURE_PAL) + /* Initialize the PAL. */ if(0 != PAL_Initialize(argc, argv)) { - return FAIL; + return FAIL; } -#endif ULONG Error = ERROR_SUCCESS; #if defined(FEATURE_EVENT_TRACE) Trace("\\n Starting functional eventing APIs tests \\n"); """) - Test_cpp.write(generateClralltestEvents(sClrEtwAllMan)) - Test_cpp.write(""" - - if (Error != ERROR_SUCCESS) - { - Fail("One or more eventing Apis failed\\n "); - return FAIL; - } - Trace("\\n All eventing APIs were fired succesfully \\n"); -#endif //defined(FEATURE_EVENT_TRACE) -#if defined(FEATURE_PAL) - + Test_cpp.write(generateClralltestEvents(sClrEtwAllMan)) + Test_cpp.write(""" /* Shutdown the PAL. -*/ - - PAL_Terminate(); -#endif - return PASS; - } + */ + + if (Error != ERROR_SUCCESS) + { + Fail("One or more eventing Apis failed\\n "); + return FAIL; + } + Trace("\\n All eventing APIs were fired succesfully \\n"); +#endif //defined(FEATURE_EVENT_TRACE) + PAL_Terminate(); + return PASS; + } """) + Cmake_file.close() + Test_cpp.close() Testinfo.close() def generateEtmDummyHeader(sClrEtwAllMan,clretwdummy): @@ -711,17 +693,19 @@ def generateEtmDummyHeader(sClrEtwAllMan,clretwdummy): if not os.path.exists(incDir): os.makedirs(incDir) - with open_for_update(clretwdummy) as Clretwdummy: - Clretwdummy.write(stdprolog + "\n") + Clretwdummy = open(clretwdummy,'w') + Clretwdummy.write(stdprolog + "\n") + + for providerNode in tree.getElementsByTagName('provider'): + templateNodes = providerNode.getElementsByTagName('template') + allTemplates = parseTemplateNodes(templateNodes) + eventNodes = providerNode.getElementsByTagName('event') + #pal: create etmdummy.h + Clretwdummy.write(generateclrEtwDummy(eventNodes, allTemplates) + "\n") - for providerNode in tree.getElementsByTagName('provider'): - templateNodes = providerNode.getElementsByTagName('template') - allTemplates = parseTemplateNodes(templateNodes) - eventNodes = providerNode.getElementsByTagName('event') - #pal: create etmdummy.h - Clretwdummy.write(generateclrEtwDummy(eventNodes, allTemplates) + "\n") + Clretwdummy.close() -def generatePlatformIndependentFiles(sClrEtwAllMan, incDir, etmDummyFile, extern): +def generatePlformIndependentFiles(sClrEtwAllMan,incDir,etmDummyFile): generateEtmDummyHeader(sClrEtwAllMan,etmDummyFile) tree = DOM.parse(sClrEtwAllMan) @@ -733,43 +717,152 @@ def generatePlatformIndependentFiles(sClrEtwAllMan, incDir, etmDummyFile, extern if not os.path.exists(incDir): os.makedirs(incDir) - # Write the main header for FireETW* functions - clrallevents = os.path.join(incDir, "clretwallmain.h") - with open_for_update(clrallevents) as Clrallevents: - Clrallevents.write(stdprolog) - Clrallevents.write(""" -#include "clrxplatevents.h" -#include "clreventpipewriteevents.h" + clrallevents = incDir + "/clretwallmain.h" + clrxplatevents = incDir + "/clrxplatevents.h" + clreventpipewriteevents = incDir + "/clreventpipewriteevents.h" -""") - for providerNode in tree.getElementsByTagName('provider'): - templateNodes = providerNode.getElementsByTagName('template') - allTemplates = parseTemplateNodes(templateNodes) - eventNodes = providerNode.getElementsByTagName('event') + Clrallevents = open(clrallevents,'w') + Clrxplatevents = open(clrxplatevents,'w') + Clreventpipewriteevents = open(clreventpipewriteevents,'w') - #vm header: - Clrallevents.write(generateClrallEvents(eventNodes, allTemplates) + "\n") + Clrallevents.write(stdprolog + "\n") + Clrxplatevents.write(stdprolog + "\n") + Clreventpipewriteevents.write(stdprolog + "\n") + Clrallevents.write("\n#include \"clrxplatevents.h\"\n") + Clrallevents.write("#include \"clreventpipewriteevents.h\"\n\n") + + for providerNode in tree.getElementsByTagName('provider'): + templateNodes = providerNode.getElementsByTagName('template') + allTemplates = parseTemplateNodes(templateNodes) + eventNodes = providerNode.getElementsByTagName('event') + #vm header: + Clrallevents.write(generateClrallEvents(eventNodes, allTemplates) + "\n") + + #pal: create clrallevents.h + Clrxplatevents.write(generateClrXplatEvents(eventNodes, allTemplates) + "\n") - # Write secondary headers for FireEtXplat* and EventPipe* functions - clrxplatevents = os.path.join(incDir, "clrxplatevents.h") - clreventpipewriteevents = os.path.join(incDir, "clreventpipewriteevents.h") - with open_for_update(clrxplatevents) as Clrxplatevents: - with open_for_update(clreventpipewriteevents) as Clreventpipewriteevents: - Clrxplatevents.write(stdprolog + "\n") - Clreventpipewriteevents.write(stdprolog + "\n") + #eventpipe: create clreventpipewriteevents.h + Clreventpipewriteevents.write(generateClrEventPipeWriteEvents(eventNodes, allTemplates) + "\n") - for providerNode in tree.getElementsByTagName('provider'): - templateNodes = providerNode.getElementsByTagName('template') - allTemplates = parseTemplateNodes(templateNodes) - eventNodes = providerNode.getElementsByTagName('event') + Clrxplatevents.close() + Clrallevents.close() + Clreventpipewriteevents.close() - #pal: create clrallevents.h - Clrxplatevents.write(generateClrXplatEvents(eventNodes, allTemplates, extern) + "\n") +class EventExclusions: + def __init__(self): + self.nostack = set() + self.explicitstack = set() + self.noclrinstance = set() + +def parseExclusionList(exclusionListFile): + ExclusionFile = open(exclusionListFile,'r') + exclusionInfo = EventExclusions() + + for line in ExclusionFile: + line = line.strip() + + #remove comments + if not line or line.startswith('#'): + continue + + tokens = line.split(':') + #entries starting with nomac are ignored + if "nomac" in tokens: + continue + + if len(tokens) > 5: + raise Exception("Invalid Entry " + line + "in "+ exclusionListFile) + + eventProvider = tokens[2] + eventTask = tokens[1] + eventSymbol = tokens[4] + + if eventProvider == '': + eventProvider = "*" + if eventTask == '': + eventTask = "*" + if eventSymbol == '': + eventSymbol = "*" + entry = eventProvider + ":" + eventTask + ":" + eventSymbol + + if tokens[0].lower() == "nostack": + exclusionInfo.nostack.add(entry) + if tokens[0].lower() == "stack": + exclusionInfo.explicitstack.add(entry) + if tokens[0].lower() == "noclrinstanceid": + exclusionInfo.noclrinstance.add(entry) + ExclusionFile.close() + + return exclusionInfo + +def getStackWalkBit(eventProvider, taskName, eventSymbol, stackSet): + for entry in stackSet: + tokens = entry.split(':') + + if len(tokens) != 3: + raise Exception("Error, possible error in the script which introduced the enrty "+ entry) + + eventCond = tokens[0] == eventProvider or tokens[0] == "*" + taskCond = tokens[1] == taskName or tokens[1] == "*" + symbolCond = tokens[2] == eventSymbol or tokens[2] == "*" + + if eventCond and taskCond and symbolCond: + return False + return True + +#Add the miscelaneous checks here +def checkConsistency(sClrEtwAllMan,exclusionListFile): + tree = DOM.parse(sClrEtwAllMan) + exclusionInfo = parseExclusionList(exclusionListFile) + for providerNode in tree.getElementsByTagName('provider'): - #eventpipe: create clreventpipewriteevents.h - Clreventpipewriteevents.write(generateClrEventPipeWriteEvents(eventNodes, allTemplates, extern) + "\n") + stackSupportSpecified = {} + eventNodes = providerNode.getElementsByTagName('event') + templateNodes = providerNode.getElementsByTagName('template') + eventProvider = providerNode.getAttribute('name') + allTemplates = parseTemplateNodes(templateNodes) + for eventNode in eventNodes: + taskName = eventNode.getAttribute('task') + eventSymbol = eventNode.getAttribute('symbol') + eventTemplate = eventNode.getAttribute('template') + eventValue = int(eventNode.getAttribute('value')) + clrInstanceBit = getStackWalkBit(eventProvider, taskName, eventSymbol, exclusionInfo.noclrinstance) + sLookupFieldName = "ClrInstanceID" + sLookupFieldType = "win:UInt16" + + if clrInstanceBit and allTemplates.get(eventTemplate): + # check for the event template and look for a field named ClrInstanceId of type win:UInt16 + fnParam = allTemplates[eventTemplate].getFnParam(sLookupFieldName) + + if not(fnParam and fnParam.winType == sLookupFieldType): + raise Exception(exclusionListFile + ":No " + sLookupFieldName + " field of type " + sLookupFieldType + " for event symbol " + eventSymbol) + + # If some versions of an event are on the nostack/stack lists, + # and some versions are not on either the nostack or stack list, + # then developer likely forgot to specify one of the versions + + eventStackBitFromNoStackList = getStackWalkBit(eventProvider, taskName, eventSymbol, exclusionInfo.nostack) + eventStackBitFromExplicitStackList = getStackWalkBit(eventProvider, taskName, eventSymbol, exclusionInfo.explicitstack) + sStackSpecificityError = exclusionListFile + ": Error processing event :" + eventSymbol + "(ID" + str(eventValue) + "): This file must contain either ALL versions of this event or NO versions of this event. Currently some, but not all, versions of this event are present\n" + + if not stackSupportSpecified.get(eventValue): + # Haven't checked this event before. Remember whether a preference is stated + if ( not eventStackBitFromNoStackList) or ( not eventStackBitFromExplicitStackList): + stackSupportSpecified[eventValue] = True + else: + stackSupportSpecified[eventValue] = False + else: + # We've checked this event before. + if stackSupportSpecified[eventValue]: + # When we last checked, a preference was previously specified, so it better be specified here + if eventStackBitFromNoStackList and eventStackBitFromExplicitStackList: + raise Exception(sStackSpecificityError) + else: + # When we last checked, a preference was not previously specified, so it better not be specified here + if ( not eventStackBitFromNoStackList) or ( not eventStackBitFromExplicitStackList): + raise Exception(sStackSpecificityError) import argparse import sys @@ -781,28 +874,28 @@ def main(argv): required = parser.add_argument_group('required arguments') required.add_argument('--man', type=str, required=True, help='full path to manifest containig the description of events') + required.add_argument('--exc', type=str, required=True, + help='full path to exclusion list') required.add_argument('--inc', type=str, default=None, help='full path to directory where the header files will be generated') required.add_argument('--dummy', type=str,default=None, help='full path to file that will have dummy definitions of FireEtw functions') required.add_argument('--testdir', type=str, default=None, help='full path to directory where the test assets will be deployed' ) - required.add_argument('--nonextern', action='store_true', - help='if specified, will not generated extern function stub headers' ) args, unknown = parser.parse_known_args(argv) if unknown: print('Unknown argument(s): ', ', '.join(unknown)) - return 1 + return const.UnknownArguments sClrEtwAllMan = args.man + exclusionListFile = args.exc incdir = args.inc etmDummyFile = args.dummy testDir = args.testdir - extern = not args.nonextern - - generatePlatformIndependentFiles(sClrEtwAllMan, incdir, etmDummyFile, extern) - generateSanityTest(sClrEtwAllMan, testDir) + checkConsistency(sClrEtwAllMan, exclusionListFile) + generatePlformIndependentFiles(sClrEtwAllMan,incdir,etmDummyFile) + generateSanityTest(sClrEtwAllMan,testDir) if __name__ == '__main__': return_code = main(sys.argv[1:]) - sys.exit(return_code)
\ No newline at end of file + sys.exit(return_code) diff --git a/src/scripts/genLttngProvider.py b/src/scripts/genXplatLttng.py index 382cb74675..9959895f5a 100644 --- a/src/scripts/genLttngProvider.py +++ b/src/scripts/genXplatLttng.py @@ -50,8 +50,7 @@ # import os -from genEventing import * -from utilities import open_for_update +from genXplatEventing import * stdprolog=""" // Licensed to the .NET Foundation under one or more agreements. @@ -61,7 +60,7 @@ stdprolog=""" /****************************************************************** DO NOT MODIFY. AUTOGENERATED FILE. -This file is generated using the logic from <root>/src/scripts/genLttngProvider.py +This file is generated using the logic from <root>/src/scripts/genXplatLttng.py ******************************************************************/ """ @@ -71,7 +70,7 @@ stdprolog_cmake=""" #****************************************************************** #DO NOT MODIFY. AUTOGENERATED FILE. -#This file is generated using the logic from <root>/src/scripts/genLttngProvider.py +#This file is generated using the logic from <root>/src/scripts/genXplatLttng.py #****************************************************************** """ @@ -160,7 +159,7 @@ def generateArgList(template): def generateFieldList(template): header = " " + " TP_FIELDS(\n" footer = "\n )\n)\n" - + if shouldPackTemplate(template): field_list = " ctf_integer(ULONG, length, length)\n" field_list += " ctf_sequence(char, __data__, __data__, ULONG, length)" @@ -210,7 +209,7 @@ def generateLttngHeader(providerName, allTemplates, eventNodes): for templateName in allTemplates: template = allTemplates[templateName] fnSig = allTemplates[templateName].signature - + lTTngHdr.append("\n#define " + templateName + "_TRACEPOINT_ARGS \\\n") #TP_ARGS @@ -290,7 +289,7 @@ def generateMethodBody(template, providerName, eventName): return "\n do_tracepoint(%s, %s);\n" % (providerName, eventName) fnSig = template.signature - + for paramName in fnSig.paramlist: fnparam = fnSig.getParam(paramName) paramname = fnparam.name @@ -299,7 +298,7 @@ def generateMethodBody(template, providerName, eventName): result.append(" INT " + paramname + "_path_size = -1;\n") result.append(" PathCharString " + paramname + "_PS;\n") result.append(" INT " + paramname + "_full_name_path_size") - result.append(" = (wcslen(" + paramname + ") + 1)*sizeof(WCHAR);\n") + result.append(" = (PAL_wcslen(" + paramname + ") + 1)*sizeof(WCHAR);\n") result.append(" CHAR* " + paramname + "_full_name = ") result.append(paramname + "_PS.OpenStringBuffer(" + paramname + "_full_name_path_size );\n") result.append(" if (" + paramname + "_full_name == NULL )") @@ -309,7 +308,7 @@ def generateMethodBody(template, providerName, eventName): #emit tracepoints fnSig = template.signature - + if not shouldPackTemplate(template): linefnbody = [" do_tracepoint(%s,\n %s" % (providerName, eventName)] @@ -361,8 +360,8 @@ def generateMethodBody(template, providerName, eventName): header = """ char stackBuffer[%s]; char *buffer = stackBuffer; - size_t offset = 0; - size_t size = %s; + int offset = 0; + int size = %s; bool fixedBuffer = true; bool success = true; @@ -402,7 +401,7 @@ def generateMethodBody(template, providerName, eventName): do_tracepoint(%s, %s, offset, buffer);\n""" % (providerName, eventName) return header + code + tracepoint + footer - + @@ -421,7 +420,7 @@ def generateLttngTpProvider(providerName, eventNodes, allTemplates): fnptype.append(eventName) fnptype.append("(\n") - + if templateName: template = allTemplates[templateName] else: @@ -490,7 +489,7 @@ def generateLttngFiles(etwmanifest,eventprovider_directory): os.makedirs(eventprovider_directory + tracepointprovider_directory) #Top level Cmake - with open_for_update(eventprovider_directory + "CMakeLists.txt") as topCmake: + with open(eventprovider_directory + "CMakeLists.txt", 'w') as topCmake: topCmake.write(stdprolog_cmake + "\n") topCmake.write("""cmake_minimum_required(VERSION 2.8.12.2) @@ -515,7 +514,7 @@ def generateLttngFiles(etwmanifest,eventprovider_directory): providerName_File = providerName_File.lower() topCmake.write(' "%s%s.cpp"\n' % (lttngevntprovPre, providerName_File)) - + topCmake.write(' "%shelpers.cpp"\n' % (lttngevntprovPre,)) topCmake.write(""") add_subdirectory(tracepointprovider) @@ -526,7 +525,7 @@ def generateLttngFiles(etwmanifest,eventprovider_directory): #TracepointProvider Cmake - with open_for_update(eventprovider_directory + tracepointprovider_directory + "/CMakeLists.txt") as tracepointprovider_Cmake: + with open(eventprovider_directory + tracepointprovider_directory + "/CMakeLists.txt", 'w') as tracepointprovider_Cmake: tracepointprovider_Cmake.write(stdprolog_cmake + "\n") tracepointprovider_Cmake.write("""cmake_minimum_required(VERSION 2.8.12.2) @@ -563,7 +562,7 @@ def generateLttngFiles(etwmanifest,eventprovider_directory): install_clr(coreclrtraceptprovider) """) - with open_for_update(eventprovider_directory + lttng_directory + "/eventprovhelpers.cpp") as helper: + with open(eventprovider_directory + lttng_directory + "/eventprovhelpers.cpp", 'w') as helper: helper.write(""" #include "palrt.h" #include "pal.h" @@ -573,81 +572,72 @@ def generateLttngFiles(etwmanifest,eventprovider_directory): #include <new> #include <memory.h> -#define wcslen PAL_wcslen - -bool ResizeBuffer(char *&buffer, size_t& size, size_t currLen, size_t newSize, bool &fixedBuffer) +bool ResizeBuffer(char *&buffer, int& size, int currLen, int newSize, bool &fixedBuffer) { - newSize = (size_t)(newSize * 1.5); - _ASSERTE(newSize > size); // check for overflow + newSize *= 1.5; + _ASSERTE(newSize > size); // check for overflow if (newSize < 32) newSize = 32; - // We can't use coreclr includes here so we use std::nothrow - // rather than the coreclr version - char *newBuffer = new (std::nothrow) char[newSize]; + char *newBuffer = new char[newSize]; - if (newBuffer == NULL) - return false; + memcpy(newBuffer, buffer, currLen); - memcpy(newBuffer, buffer, currLen); + if (!fixedBuffer) + delete[] buffer; - if (!fixedBuffer) - delete[] buffer; + buffer = newBuffer; + size = newSize; + fixedBuffer = false; - buffer = newBuffer; - size = newSize; - fixedBuffer = false; - - return true; + return true; } -bool WriteToBuffer(const BYTE *src, size_t len, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) +bool WriteToBuffer(const BYTE *src, int len, char *&buffer, int& offset, int& size, bool &fixedBuffer) { - if(!src) return true; - if (offset + len > size) - { - if (!ResizeBuffer(buffer, size, offset, size + len, fixedBuffer)) - return false; - } - - memcpy(buffer + offset, src, len); - offset += len; - return true; + if (!src) return true; + if (offset + len > size) + { + if (!ResizeBuffer(buffer, size, offset, size + len, fixedBuffer)) + return false; + } + + memcpy(buffer + offset, src, len); + offset += len; + return true; } -bool WriteToBuffer(PCWSTR str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) +bool WriteToBuffer(PCWSTR str, char *&buffer, int& offset, int& size, bool &fixedBuffer) { - if(!str) return true; - size_t byteCount = (wcslen(str) + 1) * sizeof(*str); - - if (offset + byteCount > size) - { - if (!ResizeBuffer(buffer, size, offset, size + byteCount, fixedBuffer)) - return false; - } - - memcpy(buffer + offset, str, byteCount); - offset += byteCount; - return true; + if (!str) return true; + int byteCount = (PAL_wcslen(str) + 1) * sizeof(*str); + + if (offset + byteCount > size) + { + if (!ResizeBuffer(buffer, size, offset, size + byteCount, fixedBuffer)) + return false; + } + + memcpy(buffer + offset, str, byteCount); + offset += byteCount; + return true; } -bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) +bool WriteToBuffer(const char *str, char *&buffer, int& offset, int& size, bool &fixedBuffer) { - if(!str) return true; - size_t len = strlen(str) + 1; - if (offset + len > size) - { - if (!ResizeBuffer(buffer, size, offset, size + len, fixedBuffer)) - return false; - } - - memcpy(buffer + offset, str, len); - offset += len; - return true; -} - -""") + if (!str) return true; + int len = strlen(str) + 1; + if (offset + len > size) + { + if (!ResizeBuffer(buffer, size, offset, size + len, fixedBuffer)) + return false; + } + + memcpy(buffer + offset, str, len); + offset += len; + return true; +}""") # Generate Lttng specific instrumentation for providerNode in tree.getElementsByTagName('provider'): @@ -660,19 +650,24 @@ bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, providerName_File = providerName_File.lower() providerName = providerName.replace('-','_') - lttngevntheadershortname = "tp" + providerName_File +".h" + lttngevntheadershortname = "tp" + providerName_File +".h"; lttngevntheader = eventprovider_directory + "lttng/" + lttngevntheadershortname lttngevntprov = eventprovider_directory + lttngevntprovPre + providerName_File + ".cpp" lttngevntprovTp = eventprovider_directory + lttngevntprovTpPre + providerName_File +".cpp" - templateNodes = providerNode.getElementsByTagName('template') - eventNodes = providerNode.getElementsByTagName('event') - allTemplates = parseTemplateNodes(templateNodes) + lTTngHdr = open(lttngevntheader, 'w') + lTTngImpl = open(lttngevntprov, 'w') + lTTngTpImpl = open(lttngevntprovTp, 'w') + + lTTngHdr.write(stdprolog + "\n") + lTTngImpl.write(stdprolog + "\n") + lTTngTpImpl.write(stdprolog + "\n") + lTTngTpImpl.write("\n#define TRACEPOINT_CREATE_PROBES\n") - with open_for_update(lttngevntheader) as lttnghdr_file: - lttnghdr_file.write(stdprolog + "\n") - lttnghdr_file.write(""" + lTTngTpImpl.write("#include \"./"+lttngevntheadershortname + "\"\n") + + lTTngHdr.write(""" #include "palrt.h" #include "pal.h" @@ -680,24 +675,20 @@ bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, """) - lttnghdr_file.write("#define TRACEPOINT_PROVIDER " + providerName + "\n") - lttnghdr_file.write(""" + lTTngHdr.write("#define TRACEPOINT_PROVIDER " + providerName + "\n") + lTTngHdr.write(""" #undef TRACEPOINT_INCLUDE """) - lttnghdr_file.write("#define TRACEPOINT_INCLUDE \"./" + lttngevntheadershortname + "\"\n\n") - - lttnghdr_file.write("#if !defined(LTTNG_CORECLR_H" + providerName + ") || defined(TRACEPOINT_HEADER_MULTI_READ)\n\n") - lttnghdr_file.write("#define LTTNG_CORECLR_H" + providerName + "\n") + lTTngHdr.write("#define TRACEPOINT_INCLUDE \"./" + lttngevntheadershortname + "\"\n\n") - lttnghdr_file.write("\n#include <lttng/tracepoint.h>\n\n") + lTTngHdr.write("#if !defined(LTTNG_CORECLR_H" + providerName + ") || defined(TRACEPOINT_HEADER_MULTI_READ)\n\n") + lTTngHdr.write("#define LTTNG_CORECLR_H" + providerName + "\n") - lttnghdr_file.write(generateLttngHeader(providerName,allTemplates,eventNodes) + "\n") + lTTngHdr.write("\n#include <lttng/tracepoint.h>\n\n") - with open_for_update(lttngevntprov) as lttngimpl_file: - lttngimpl_file.write(stdprolog + "\n") - lttngimpl_file.write(""" + lTTngImpl.write(""" #define TRACEPOINT_DEFINE #define TRACEPOINT_PROBE_DYNAMIC_LINKAGE @@ -709,43 +700,48 @@ bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, #define PAL_realloc realloc #include "pal/stackstring.hpp" """) - lttngimpl_file.write("#include \"" + lttngevntheadershortname + "\"\n\n") + lTTngImpl.write("#include \"" + lttngevntheadershortname + "\"\n\n") - lttngimpl_file.write("""#ifndef tracepoint_enabled + lTTngImpl.write("""#ifndef tracepoint_enabled #define tracepoint_enabled(provider, name) TRUE #define do_tracepoint tracepoint #endif -#define wcslen PAL_wcslen -bool ResizeBuffer(char *&buffer, size_t& size, size_t currLen, size_t newSize, bool &fixedBuffer); -bool WriteToBuffer(PCWSTR str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer); -bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer); -bool WriteToBuffer(const BYTE *src, size_t len, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer); +bool ResizeBuffer(char *&buffer, int& size, int currLen, int newSize, bool &fixedBuffer); +bool WriteToBuffer(PCWSTR str, char *&buffer, int& offset, int& size, bool &fixedBuffer); +bool WriteToBuffer(const char *str, char *&buffer, int& offset, int& size, bool &fixedBuffer); +bool WriteToBuffer(const BYTE *src, int len, char *&buffer, int& offset, int& size, bool &fixedBuffer); template <typename T> -bool WriteToBuffer(const T &value, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) +bool WriteToBuffer(const T &value, char *&buffer, int& offset, int& size, bool &fixedBuffer) { - if (sizeof(T) + offset > size) - { - if (!ResizeBuffer(buffer, size, offset, size + sizeof(T), fixedBuffer)) - return false; - } - - *(T *)(buffer + offset) = value; - offset += sizeof(T); - return true; + if (sizeof(T) + offset > size) + { + if (!ResizeBuffer(buffer, size, offset, size + sizeof(T), fixedBuffer)) + return false; + } + + *(T *)(buffer + offset) = value; + offset += sizeof(T); + return true; } """) - lttngimpl_file.write(generateLttngTpProvider(providerName,eventNodes,allTemplates) + "\n") - with open_for_update(lttngevntprovTp) as tpimpl_file: - tpimpl_file.write(stdprolog + "\n") + templateNodes = providerNode.getElementsByTagName('template') + eventNodes = providerNode.getElementsByTagName('event') + + allTemplates = parseTemplateNodes(templateNodes) + #generate the header + lTTngHdr.write(generateLttngHeader(providerName,allTemplates,eventNodes) + "\n") - tpimpl_file.write("\n#define TRACEPOINT_CREATE_PROBES\n") + #create the implementation of eventing functions : lttngeventprov*.cp + lTTngImpl.write(generateLttngTpProvider(providerName,eventNodes,allTemplates) + "\n") - tpimpl_file.write("#include \"./"+lttngevntheadershortname + "\"\n") + lTTngHdr.close() + lTTngImpl.close() + lTTngTpImpl.close() import argparse import sys @@ -763,7 +759,7 @@ def main(argv): args, unknown = parser.parse_known_args(argv) if unknown: print('Unknown argument(s): ', ', '.join(unknown)) - return 1 + return const.UnknownArguments sClrEtwAllMan = args.man intermediate = args.intermediate @@ -772,4 +768,4 @@ def main(argv): if __name__ == '__main__': return_code = main(sys.argv[1:]) - sys.exit(return_code)
\ No newline at end of file + sys.exit(return_code) diff --git a/src/scripts/utilities.py b/src/scripts/utilities.py deleted file mode 100644 index 6898bb7542..0000000000 --- a/src/scripts/utilities.py +++ /dev/null @@ -1,106 +0,0 @@ -from filecmp import dircmp -from hashlib import sha256 -from io import StringIO -import shutil -import os - -class WrappedStringIO(StringIO): - """A wrapper around StringIO to allow writing str objects""" - def write(self, s): - if isinstance(s, str): - s = unicode(s) - super(WrappedStringIO, self).write(s) - -class UpdateFileWriter: - """A file-like context object which will only write to a file if the result would be different - - Attributes: - filename (str): The name of the file to update - stream (WrappedStringIO): The file-like stream provided upon context enter - - Args: - filename (str): Sets the filename attribute - """ - filemode = 'w' - - def __init__(self, filename): - self.filename = filename - self.stream = None - - def __enter__(self): - self.stream = WrappedStringIO() - return self.stream - - def __exit__(self, exc_type, exc_value, traceback): - if exc_value is None: - new_content = self.stream.getvalue() - new_hash = sha256() - cur_hash = sha256() - - try: - with open(self.filename, 'r') as fstream: - cur_hash.update(fstream.read()) - file_found = True - except IOError: - file_found = False - - if file_found: - new_hash.update(new_content) - update = new_hash.digest() != cur_hash.digest() - else: - update = True - - if update: - with open(self.filename, 'w') as fstream: - fstream.write(new_content) - - self.stream.close() - -def open_for_update(filename): - return UpdateFileWriter(filename) - -def walk_recursively_and_update(dcmp): - #for different Files Copy from right to left - for name in dcmp.diff_files: - srcpath = dcmp.right + "/" + name - destpath = dcmp.left + "/" + name - print("Updating %s" % (destpath)) - if os.path.isfile(srcpath): - shutil.copyfile(srcpath, destpath) - else : - raise Exception("path: " + srcpath + "is neither a file or folder") - - #copy right only files - for name in dcmp.right_only: - srcpath = dcmp.right + "/" + name - destpath = dcmp.left + "/" + name - print("Updating %s" % (destpath)) - if os.path.isfile(srcpath): - shutil.copyfile(srcpath, destpath) - elif os.path.isdir(srcpath): - shutil.copytree(srcpath, destpath) - else : - raise Exception("path: " + srcpath + "is neither a file or folder") - - #delete left only files - for name in dcmp.left_only: - path = dcmp.left + "/" + name - print("Deleting %s" % (path)) - if os.path.isfile(path): - os.remove(path) - elif os.path.isdir(path): - shutil.rmtree(path) - else : - raise Exception("path: " + path + "is neither a file or folder") - - #call recursively - for sub_dcmp in dcmp.subdirs.values(): - walk_recursively_and_update(sub_dcmp) - -def UpdateDirectory(destpath,srcpath): - - print("Updating %s with %s" % (destpath,srcpath)) - if not os.path.exists(destpath): - os.makedirs(destpath) - dcmp = dircmp(destpath,srcpath) - walk_recursively_and_update(dcmp) diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt index 97ab656f81..f49d01bc91 100644 --- a/src/vm/CMakeLists.txt +++ b/src/vm/CMakeLists.txt @@ -1,7 +1,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) # Needed due to the cmunged files being in the binary folders, the set(CMAKE_INCLUDE_CURRENT_DIR ON) is not enough -include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${ARCH_SOURCES_DIR}) add_definitions(-DUNICODE) @@ -9,7 +9,7 @@ add_definitions(-D_UNICODE) if(CMAKE_CONFIGURATION_TYPES) # multi-configuration generator? - foreach (Config DEBUG CHECKED) + foreach (Config DEBUG CHECKED) set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:${Config}>:WRITE_BARRIER_CHECK=1>) endforeach (Config) else() @@ -291,7 +291,7 @@ set(VM_SOURCES_DAC_AND_WKS_WIN32 winrttypenameconverter.cpp ) -list(APPEND VM_SOURCES_WKS +list(APPEND VM_SOURCES_WKS ${VM_SOURCES_DAC_AND_WKS_WIN32} # These should not be included for Linux appxutil.cpp @@ -313,17 +313,17 @@ list(APPEND VM_SOURCES_WKS extensibleclassfactory.cpp mngstdinterfaces.cpp notifyexternals.cpp - olecontexthelpers.cpp + olecontexthelpers.cpp rcwrefcache.cpp rtlfunctions.cpp runtimecallablewrapper.cpp stacksampler.cpp stdinterfaces.cpp stdinterfaces_wrapper.cpp - winrthelpers.cpp + winrthelpers.cpp ) -list(APPEND VM_SOURCES_DAC +list(APPEND VM_SOURCES_DAC ${VM_SOURCES_DAC_AND_WKS_WIN32} # These should not be included for Linux clrprivbinderwinrt.cpp @@ -423,7 +423,7 @@ else(WIN32) ${ARCH_SOURCES_DIR}/pinvokestubs.S ) endif() - + endif(WIN32) @@ -434,7 +434,7 @@ if(CLR_CMAKE_TARGET_ARCH_AMD64) ${ARCH_SOURCES_DIR}/gmsamd64.cpp ${ARCH_SOURCES_DIR}/stublinkeramd64.cpp ) - + set(VM_SOURCES_WKS_ARCH ${ARCH_SOURCES_DIR}/jithelpersamd64.cpp ${ARCH_SOURCES_DIR}/jitinterfaceamd64.cpp @@ -452,7 +452,7 @@ elseif(CLR_CMAKE_TARGET_ARCH_I386) ${ARCH_SOURCES_DIR}/gmsx86.cpp ${ARCH_SOURCES_DIR}/stublinkerx86.cpp ) - + set(VM_SOURCES_WKS_ARCH ${ARCH_SOURCES_DIR}/jitinterfacex86.cpp ${ARCH_SOURCES_DIR}/profiler.cpp @@ -465,7 +465,7 @@ elseif(CLR_CMAKE_TARGET_ARCH_ARM) ${ARCH_SOURCES_DIR}/stubs.cpp ${ARCH_SOURCES_DIR}/armsinglestepper.cpp ) - + set(VM_SOURCES_WKS_ARCH ${ARCH_SOURCES_DIR}/jithelpersarm.cpp ${ARCH_SOURCES_DIR}/profiler.cpp @@ -492,7 +492,7 @@ set(VM_SOURCES_DAC_ARCH exceptionhandling.cpp ) -list(APPEND VM_SOURCES_WKS +list(APPEND VM_SOURCES_WKS ${VM_SOURCES_WKS_ARCH} ${VM_SOURCES_DAC_AND_WKS_ARCH} ) @@ -519,6 +519,6 @@ convert_to_absolute_path(VM_SOURCES_DAC ${VM_SOURCES_DAC}) add_subdirectory(dac) add_subdirectory(wks) -if(FEATURE_PERFTRACING) - add_subdirectory(${GENERATED_EVENTING_DIR}/eventpipe ${CMAKE_CURRENT_BINARY_DIR}/eventpipe) -endif(FEATURE_PERFTRACING)
\ No newline at end of file +if(CLR_CMAKE_PLATFORM_LINUX) + add_subdirectory($ENV{__IntermediatesDir}/Generated/eventpipe ${CMAKE_CURRENT_BINARY_DIR}/eventpipe) +endif(CLR_CMAKE_PLATFORM_LINUX) diff --git a/src/vm/eventpipe.cpp b/src/vm/eventpipe.cpp index 37de4c3b36..8f2e8ff937 100644 --- a/src/vm/eventpipe.cpp +++ b/src/vm/eventpipe.cpp @@ -2,9 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#include "common.h" #include "clrtypes.h" #include "safemath.h" +#include "common.h" #include "eventpipe.h" #include "eventpipebuffermanager.h" #include "eventpipeconfiguration.h" @@ -33,8 +33,11 @@ EventPipeJsonFile* EventPipe::s_pJsonFile = NULL; #ifdef FEATURE_PAL // This function is auto-generated from /src/scripts/genEventPipe.py extern "C" void InitProvidersAndEvents(); -#else -void InitProvidersAndEvents(); +#endif + +#ifdef FEATURE_PAL +// This function is auto-generated from /src/scripts/genEventPipe.py +extern "C" void InitProvidersAndEvents(); #endif EventPipeEventPayload::EventPipeEventPayload(BYTE *pData, unsigned int length) @@ -94,7 +97,7 @@ EventPipeEventPayload::~EventPipeEventPayload() CONTRACTL { NOTHROW; - GC_NOTRIGGER; + GC_TRIGGERS; MODE_ANY; } CONTRACTL_END; @@ -111,7 +114,7 @@ void EventPipeEventPayload::Flatten() CONTRACTL { NOTHROW; - GC_NOTRIGGER; + GC_TRIGGERS; MODE_ANY; } CONTRACTL_END; @@ -165,7 +168,7 @@ BYTE* EventPipeEventPayload::GetFlatData() CONTRACTL { NOTHROW; - GC_NOTRIGGER; + GC_TRIGGERS; MODE_ANY; } CONTRACTL_END; @@ -190,9 +193,11 @@ void EventPipe::Initialize() s_pBufferManager = new EventPipeBufferManager(); +#ifdef FEATURE_PAL // This calls into auto-generated code to initialize the runtime providers // and events so that the EventPipe configuration lock isn't taken at runtime InitProvidersAndEvents(); +#endif } void EventPipe::EnableOnStartup() @@ -222,19 +227,13 @@ void EventPipe::Shutdown() { CONTRACTL { - NOTHROW; + THROWS; GC_TRIGGERS; MODE_ANY; } CONTRACTL_END; - // We are shutting down, so if diasabling EventPipe throws, we need to move along anyway - EX_TRY - { - Disable(); - } - EX_CATCH { } - EX_END_CATCH(SwallowAllExceptions); + Disable(); if(s_pConfig != NULL) { @@ -263,13 +262,7 @@ void EventPipe::Enable( CONTRACTL_END; // If tracing is not initialized or is already enabled, bail here. - if(!s_tracingInitialized || s_pConfig == NULL || s_pConfig->Enabled()) - { - return; - } - - // If the state or aurguments are invalid, bail - if(pProviders == NULL || numProviders <= 0) + if(!s_tracingInitialized || s_pConfig->Enabled()) { return; } @@ -319,7 +312,7 @@ void EventPipe::Disable() // Take the lock before disabling tracing. CrstHolder _crst(GetLock()); - if(s_pConfig != NULL && s_pConfig->Enabled()) + if(s_pConfig->Enabled()) { // Disable the profiler. SampleProfiler::Disable(); @@ -475,6 +468,7 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload NOTHROW; GC_NOTRIGGER; MODE_ANY; + PRECONDITION(s_pBufferManager != NULL); } CONTRACTL_END; @@ -492,12 +486,6 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload return; } - if(s_pConfig == NULL) - { - // We can't procede without a configuration - return; - } - if(!s_pConfig->RundownEnabled() && s_pBufferManager != NULL) { if(!s_pBufferManager->WriteEvent(pThread, event, payload, pActivityId, pRelatedActivityId)) @@ -513,10 +501,6 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload { // Write synchronously to the file. // We're under lock and blocking the disabling thread. - // This copy occurs here (rather than at file write) because - // A) The FastSerializer API would need to change if we waited - // B) It is unclear there is a benefit to multiple file write calls - // as opposed a a buffer copy here EventPipeEventInstance instance( event, pThread->GetOSThreadId(), @@ -527,22 +511,12 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload if(s_pFile != NULL) { - // EventPipeFile::WriteEvent needs to allocate a metadata event - // and can therefore throw. In this context we will silently - // fail rather than disrupt the caller - EX_TRY - { - s_pFile->WriteEvent(instance); - } - EX_CATCH { } - EX_END_CATCH(SwallowAllExceptions); + s_pFile->WriteEvent(instance); } } } -// This section requires a call to GCX_PREEMP which violates the GC_NOTRIGGER contract -// It should only be enabled when debugging this specific component and contracts are off -#ifdef DEBUG_JSON_EVENT_FILE +#ifdef _DEBUG { GCX_PREEMP(); @@ -563,7 +537,7 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload { s_pSyncFile->WriteEvent(instance); } - + // Write to the EventPipeJsonFile if it exists. if(s_pJsonFile != NULL) { @@ -571,7 +545,7 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload } } } -#endif // DEBUG_JSON_EVENT_FILE +#endif // _DEBUG } void EventPipe::WriteSampleProfileEvent(Thread *pSamplingThread, EventPipeEvent *pEvent, Thread *pTargetThread, StackContents &stackContents, BYTE *pData, unsigned int length) @@ -667,7 +641,7 @@ StackWalkAction EventPipe::StackWalkCallback(CrawlFrame *pCf, StackContents *pDa { NOTHROW; GC_NOTRIGGER; - MODE_ANY; + MODE_PREEMPTIVE; PRECONDITION(pCf != NULL); PRECONDITION(pData != NULL); } @@ -712,15 +686,15 @@ CrstStatic* EventPipe::GetLock() void QCALLTYPE EventPipeInternal::Enable( __in_z LPCWSTR outputFile, - UINT32 circularBufferSizeInMB, - INT64 profilerSamplingRateInNanoseconds, + unsigned int circularBufferSizeInMB, + long profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration *pProviders, - INT32 numProviders) + int numProviders) { QCALL_CONTRACT; BEGIN_QCALL; - SampleProfiler::SetSamplingRate((unsigned long)profilerSamplingRateInNanoseconds); + SampleProfiler::SetSamplingRate(profilerSamplingRateInNanoseconds); EventPipe::Enable(outputFile, circularBufferSizeInMB, pProviders, numProviders); END_QCALL; } @@ -753,12 +727,12 @@ INT_PTR QCALLTYPE EventPipeInternal::CreateProvider( INT_PTR QCALLTYPE EventPipeInternal::DefineEvent( INT_PTR provHandle, - UINT32 eventID, + unsigned int eventID, __int64 keywords, - UINT32 eventVersion, - UINT32 level, + unsigned int eventVersion, + unsigned int level, void *pMetadata, - UINT32 metadataLength) + unsigned int metadataLength) { QCALL_CONTRACT; @@ -794,9 +768,9 @@ void QCALLTYPE EventPipeInternal::DeleteProvider( void QCALLTYPE EventPipeInternal::WriteEvent( INT_PTR eventHandle, - UINT32 eventID, + unsigned int eventID, void *pData, - UINT32 length, + unsigned int length, LPCGUID pActivityId, LPCGUID pRelatedActivityId) { @@ -812,9 +786,9 @@ void QCALLTYPE EventPipeInternal::WriteEvent( void QCALLTYPE EventPipeInternal::WriteEventData( INT_PTR eventHandle, - UINT32 eventID, + unsigned int eventID, EventData **pEventData, - UINT32 eventDataCount, + unsigned int eventDataCount, LPCGUID pActivityId, LPCGUID pRelatedActivityId) { diff --git a/src/vm/eventpipe.h b/src/vm/eventpipe.h index 4fd3d88127..bac7be6ac8 100644 --- a/src/vm/eventpipe.h +++ b/src/vm/eventpipe.h @@ -6,10 +6,8 @@ #define __EVENTPIPE_H__ #ifdef FEATURE_PERFTRACING -#include "common.h" class CrstStatic; -class CrawlFrame; class EventPipeConfiguration; class EventPipeEvent; class EventPipeFile; @@ -60,7 +58,7 @@ public: // If a buffer was allocated internally, delete it ~EventPipeEventPayload(); - + // Copy the data (whether flat or array of objects) into a flat buffer at pDst // Assumes that pDst points to an appropriatly sized buffer void CopyData(BYTE *pDst); @@ -261,7 +259,7 @@ class EventPipe // Write out a sample profile event. static void WriteSampleProfileEvent(Thread *pSamplingThread, EventPipeEvent *pEvent, Thread *pTargetThread, StackContents &stackContents, BYTE *pData = NULL, unsigned int length = 0); - + // Get the managed call stack for the current thread. static bool WalkManagedStackForCurrentThread(StackContents &stackContents); @@ -303,7 +301,7 @@ private: LPCWSTR m_pProviderName; UINT64 m_keywords; - UINT32 m_loggingLevel; + unsigned int m_loggingLevel; public: @@ -318,7 +316,7 @@ public: EventPipeProviderConfiguration( LPCWSTR pProviderName, UINT64 keywords, - UINT32 loggingLevel) + unsigned int loggingLevel) { LIMITED_METHOD_CONTRACT; m_pProviderName = pProviderName; @@ -338,7 +336,7 @@ public: return m_keywords; } - UINT32 GetLevel() const + unsigned int GetLevel() const { LIMITED_METHOD_CONTRACT; return m_loggingLevel; @@ -352,10 +350,10 @@ public: static void QCALLTYPE Enable( __in_z LPCWSTR outputFile, - UINT32 circularBufferSizeInMB, - INT64 profilerSamplingRateInNanoseconds, + unsigned int circularBufferSizeInMB, + long profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration *pProviders, - INT32 numProviders); + int numProviders); static void QCALLTYPE Disable(); @@ -365,28 +363,28 @@ public: static INT_PTR QCALLTYPE DefineEvent( INT_PTR provHandle, - UINT32 eventID, + unsigned int eventID, __int64 keywords, - UINT32 eventVersion, - UINT32 level, + unsigned int eventVersion, + unsigned int level, void *pMetadata, - UINT32 metadataLength); + unsigned int metadataLength); static void QCALLTYPE DeleteProvider( INT_PTR provHandle); static void QCALLTYPE WriteEvent( INT_PTR eventHandle, - UINT32 eventID, + unsigned int eventID, void *pData, - UINT32 length, + unsigned int length, LPCGUID pActivityId, LPCGUID pRelatedActivityId); static void QCALLTYPE WriteEventData( INT_PTR eventHandle, - UINT32 eventID, + unsigned int eventID, EventData **pEventData, - UINT32 eventDataCount, + unsigned int eventDataCount, LPCGUID pActivityId, LPCGUID pRelatedActivityId); }; diff --git a/src/vm/eventpipebuffer.cpp b/src/vm/eventpipebuffer.cpp index 407c875fa6..80b4a4f1b7 100644 --- a/src/vm/eventpipebuffer.cpp +++ b/src/vm/eventpipebuffer.cpp @@ -35,7 +35,7 @@ EventPipeBuffer::~EventPipeBuffer() { CONTRACTL { - NOTHROW; + THROWS; GC_NOTRIGGER; MODE_ANY; } @@ -52,7 +52,7 @@ bool EventPipeBuffer::WriteEvent(Thread *pThread, EventPipeEvent &event, EventPi CONTRACTL { NOTHROW; - GC_NOTRIGGER; + GC_TRIGGERS; MODE_ANY; PRECONDITION(pThread != NULL); } @@ -143,7 +143,7 @@ EventPipeEventInstance* EventPipeBuffer::GetNext(EventPipeEventInstance *pEvent, CONTRACTL { NOTHROW; - GC_NOTRIGGER; + GC_TRIGGERS; MODE_ANY; } CONTRACTL_END; diff --git a/src/vm/eventpipebuffermanager.cpp b/src/vm/eventpipebuffermanager.cpp index 045e1d999a..e7d97d5732 100644 --- a/src/vm/eventpipebuffermanager.cpp +++ b/src/vm/eventpipebuffermanager.cpp @@ -37,7 +37,7 @@ EventPipeBufferManager::~EventPipeBufferManager() { CONTRACTL { - NOTHROW; + THROWS; GC_TRIGGERS; MODE_ANY; } @@ -80,7 +80,7 @@ EventPipeBuffer* EventPipeBufferManager::AllocateBufferForThread(Thread *pThread { CONTRACTL { - NOTHROW; + THROWS; GC_NOTRIGGER; MODE_ANY; PRECONDITION(pThread != NULL); @@ -97,19 +97,8 @@ EventPipeBuffer* EventPipeBufferManager::AllocateBufferForThread(Thread *pThread EventPipeBufferList *pThreadBufferList = pThread->GetEventPipeBufferList(); if(pThreadBufferList == NULL) { - pThreadBufferList = new (nothrow) EventPipeBufferList(this); - if (pThreadBufferList == NULL) - { - return NULL; - } - - SListElem<EventPipeBufferList*> *pElem = new (nothrow) SListElem<EventPipeBufferList*>(pThreadBufferList); - if (pElem == NULL) - { - return NULL; - } - - m_pPerThreadBufferList->InsertTail(pElem); + pThreadBufferList = new EventPipeBufferList(this); + m_pPerThreadBufferList->InsertTail(new SListElem<EventPipeBufferList*>(pThreadBufferList)); pThread->SetEventPipeBufferList(pThreadBufferList); allocateNewBuffer = true; } @@ -192,24 +181,7 @@ EventPipeBuffer* EventPipeBufferManager::AllocateBufferForThread(Thread *pThread bufferSize = requestSize; } - // EX_TRY is used here as opposed to new (nothrow) because - // the constructor also allocates a private buffer, which - // could throw, and cannot be easily checked - EX_TRY - { - pNewBuffer = new EventPipeBuffer(bufferSize); - } - EX_CATCH - { - pNewBuffer = NULL; - } - EX_END_CATCH(SwallowAllExceptions); - - if (pNewBuffer == NULL) - { - return NULL; - } - + pNewBuffer = new EventPipeBuffer(bufferSize); m_sizeOfAllBuffers += bufferSize; #ifdef _DEBUG m_numBuffersAllocated++; @@ -230,7 +202,7 @@ EventPipeBufferList* EventPipeBufferManager::FindThreadToStealFrom() { CONTRACTL { - NOTHROW; + THROWS; GC_NOTRIGGER; MODE_ANY; PRECONDITION(m_lock.OwnedByCurrentThread()); @@ -390,7 +362,7 @@ void EventPipeBufferManager::WriteAllBuffersToFile(EventPipeFile *pFile, LARGE_I { CONTRACTL { - THROWS; + NOTHROW; GC_NOTRIGGER; MODE_ANY; PRECONDITION(pFile != NULL); diff --git a/src/vm/eventpipeconfiguration.cpp b/src/vm/eventpipeconfiguration.cpp index a74bdbc28f..ae1dd4e099 100644 --- a/src/vm/eventpipeconfiguration.cpp +++ b/src/vm/eventpipeconfiguration.cpp @@ -20,7 +20,6 @@ EventPipeConfiguration::EventPipeConfiguration() m_rundownEnabled = false; m_circularBufferSizeInBytes = 1024 * 1024 * 1000; // Default to 1000MB. m_pEnabledProviderList = NULL; - m_pConfigProvider = NULL; m_pProviderList = new SList<SListElem<EventPipeProvider*>>(); } @@ -28,7 +27,7 @@ EventPipeConfiguration::~EventPipeConfiguration() { CONTRACTL { - NOTHROW; + THROWS; GC_TRIGGERS; MODE_ANY; } @@ -36,15 +35,8 @@ EventPipeConfiguration::~EventPipeConfiguration() if(m_pConfigProvider != NULL) { - // This unregisters the provider, which takes a - // HOST_BREAKABLE lock - EX_TRY - { - DeleteProvider(m_pConfigProvider); - m_pConfigProvider = NULL; - } - EX_CATCH { } - EX_END_CATCH(SwallowAllExceptions); + delete(m_pConfigProvider); + m_pConfigProvider = NULL; } if(m_pEnabledProviderList != NULL) @@ -55,28 +47,19 @@ EventPipeConfiguration::~EventPipeConfiguration() if(m_pProviderList != NULL) { - // We swallow exceptions here because the HOST_BREAKABLE - // lock may throw and this destructor gets called in throw - // intolerant places. If that happens the provider list will leak - EX_TRY - { - // Take the lock before manipulating the list. - CrstHolder _crst(EventPipe::GetLock()); + // Take the lock before manipulating the provider list. + CrstHolder _crst(EventPipe::GetLock()); - SListElem<EventPipeProvider*> *pElem = m_pProviderList->GetHead(); - while(pElem != NULL) - { - // We don't delete provider itself because it can be in-use - SListElem<EventPipeProvider*> *pCurElem = pElem; - pElem = m_pProviderList->GetNext(pElem); - delete(pCurElem); - } - - delete(m_pProviderList); + SListElem<EventPipeProvider*> *pElem = m_pProviderList->GetHead(); + while(pElem != NULL) + { + // We don't delete provider itself because it can be in-use + SListElem<EventPipeProvider*> *pCurElem = pElem; + pElem = m_pProviderList->GetNext(pElem); + delete(pCurElem); } - EX_CATCH { } - EX_END_CATCH(SwallowAllExceptions); + delete(m_pProviderList); m_pProviderList = NULL; } } @@ -127,7 +110,7 @@ void EventPipeConfiguration::DeleteProvider(EventPipeProvider *pProvider) CONTRACTL { THROWS; - GC_TRIGGERS; + GC_NOTRIGGER; MODE_ANY; PRECONDITION(pProvider != NULL); } @@ -194,7 +177,7 @@ bool EventPipeConfiguration::UnregisterProvider(EventPipeProvider &provider) CONTRACTL { THROWS; - GC_TRIGGERS; + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -288,7 +271,7 @@ size_t EventPipeConfiguration::GetCircularBufferSize() const void EventPipeConfiguration::SetCircularBufferSize(size_t circularBufferSize) { LIMITED_METHOD_CONTRACT; - + if(!m_enabled) { m_circularBufferSizeInBytes = circularBufferSize; @@ -501,7 +484,9 @@ void EventPipeConfiguration::DeleteDeferredProviders() pElem = m_pProviderList->GetNext(pElem); if(pProvider->GetDeleteDeferred()) { - DeleteProvider(pProvider); + // The act of deleting the provider unregisters it, + // removes it from the list, and deletes the list element + delete(pProvider); } } } @@ -540,7 +525,7 @@ EventPipeEnabledProviderList::EventPipeEnabledProviderList( } m_pProviders = new EventPipeEnabledProvider[m_numProviders]; - for(unsigned int i=0; i<m_numProviders; i++) + for(int i=0; i<m_numProviders; i++) { m_pProviders[i].Set( pConfigs[i].GetProviderName(), @@ -553,7 +538,7 @@ EventPipeEnabledProviderList::~EventPipeEnabledProviderList() { CONTRACTL { - NOTHROW; + THROWS; GC_NOTRIGGER; MODE_ANY; } @@ -597,7 +582,7 @@ EventPipeEnabledProvider* EventPipeEnabledProviderList::GetEnabledProvider( LPCWSTR providerName = providerNameStr.GetUnicode(); EventPipeEnabledProvider *pEnabledProvider = NULL; - for(unsigned int i=0; i<m_numProviders; i++) + for(int i=0; i<m_numProviders; i++) { EventPipeEnabledProvider *pCandidate = &m_pProviders[i]; if(pCandidate != NULL) @@ -624,7 +609,7 @@ EventPipeEnabledProvider::~EventPipeEnabledProvider() { CONTRACTL { - NOTHROW; + THROWS; GC_NOTRIGGER; MODE_ANY; } @@ -655,7 +640,7 @@ void EventPipeEnabledProvider::Set(LPCWSTR providerName, UINT64 keywords, EventP if(providerName != NULL) { - size_t bufSize = wcslen(providerName) + 1; + unsigned int bufSize = wcslen(providerName) + 1; m_pProviderName = new WCHAR[bufSize]; wcscpy_s(m_pProviderName, bufSize, providerName); } diff --git a/src/vm/eventpipeevent.cpp b/src/vm/eventpipeevent.cpp index 1b2d4ebe40..abf942b253 100644 --- a/src/vm/eventpipeevent.cpp +++ b/src/vm/eventpipeevent.cpp @@ -40,14 +40,6 @@ EventPipeEvent::EventPipeEvent(EventPipeProvider &provider, INT64 keywords, unsi EventPipeEvent::~EventPipeEvent() { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - if (m_pMetadata != NULL) { delete[] m_pMetadata; diff --git a/src/vm/eventpipeeventinstance.cpp b/src/vm/eventpipeeventinstance.cpp index 6cb7438639..305b6dac04 100644 --- a/src/vm/eventpipeeventinstance.cpp +++ b/src/vm/eventpipeeventinstance.cpp @@ -20,8 +20,8 @@ EventPipeEventInstance::EventPipeEventInstance( { CONTRACTL { - NOTHROW; - GC_NOTRIGGER; + THROWS; + GC_TRIGGERS; MODE_ANY; } CONTRACTL_END; @@ -102,8 +102,8 @@ void EventPipeEventInstance::FastSerialize(FastSerializer *pSerializer, StreamLa { CONTRACTL { - NOTHROW; - GC_NOTRIGGER; + THROWS; + GC_TRIGGERS; MODE_ANY; } CONTRACTL_END; diff --git a/src/vm/eventpipefile.cpp b/src/vm/eventpipefile.cpp index ba4eb39b29..26e04480ee 100644 --- a/src/vm/eventpipefile.cpp +++ b/src/vm/eventpipefile.cpp @@ -62,7 +62,7 @@ EventPipeFile::~EventPipeFile() { CONTRACTL { - NOTHROW; + THROWS; GC_TRIGGERS; MODE_ANY; } @@ -87,7 +87,7 @@ void EventPipeFile::WriteEvent(EventPipeEventInstance &instance) CONTRACTL { THROWS; - GC_NOTRIGGER; + GC_TRIGGERS; MODE_ANY; } CONTRACTL_END; @@ -126,8 +126,8 @@ StreamLabel EventPipeFile::GetMetadataLabel(EventPipeEvent &event) { CONTRACTL { - NOTHROW; - GC_NOTRIGGER; + THROWS; + GC_TRIGGERS; MODE_ANY; } CONTRACTL_END; @@ -147,7 +147,7 @@ void EventPipeFile::SaveMetadataLabel(EventPipeEvent &event, StreamLabel label) CONTRACTL { THROWS; - GC_NOTRIGGER; + GC_TRIGGERS; MODE_ANY; PRECONDITION(label > 0); } diff --git a/src/vm/eventpipejsonfile.cpp b/src/vm/eventpipejsonfile.cpp index aa60df7b07..2edd6f4366 100644 --- a/src/vm/eventpipejsonfile.cpp +++ b/src/vm/eventpipejsonfile.cpp @@ -38,7 +38,7 @@ EventPipeJsonFile::~EventPipeJsonFile() { CONTRACTL { - NOTHROW; + THROWS; GC_TRIGGERS; MODE_ANY; } @@ -59,26 +59,14 @@ EventPipeJsonFile::~EventPipeJsonFile() void EventPipeJsonFile::WriteEvent(EventPipeEventInstance &instance) { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; + STANDARD_VM_CONTRACT; instance.SerializeToJsonFile(this); } void EventPipeJsonFile::WriteEvent(LARGE_INTEGER timeStamp, DWORD threadID, SString &message, StackContents &stackContents) { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; + STANDARD_VM_CONTRACT; if(m_pFileStream == NULL || m_writeErrorEncountered) { @@ -110,7 +98,7 @@ void EventPipeJsonFile::Write(SString &str) { CONTRACTL { - NOTHROW; + THROWS; GC_TRIGGERS; MODE_ANY; } @@ -118,35 +106,19 @@ void EventPipeJsonFile::Write(SString &str) StackScratchBuffer scratch; const char * charStr = str.GetANSI(scratch); + ULONG inCount = str.GetCount(); + ULONG outCount; + m_pFileStream->Write(charStr, inCount, &outCount); - EX_TRY - { - ULONG inCount = str.GetCount(); - ULONG outCount; - - m_pFileStream->Write(charStr, inCount, &outCount); - - if(inCount != outCount) - { - m_writeErrorEncountered = true; - } - } - EX_CATCH + if(inCount != outCount) { m_writeErrorEncountered = true; } - EX_END_CATCH(SwallowAllExceptions); } void EventPipeJsonFile::FormatCallStack(StackContents &stackContents, SString &resultStr) { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; + STANDARD_VM_CONTRACT; StackScratchBuffer scratch; SString frameStr; diff --git a/src/vm/eventpipeprovider.cpp b/src/vm/eventpipeprovider.cpp index 84a90e4abb..c10dd33638 100644 --- a/src/vm/eventpipeprovider.cpp +++ b/src/vm/eventpipeprovider.cpp @@ -24,7 +24,6 @@ EventPipeProvider::EventPipeProvider(EventPipeConfiguration *pConfig, const SStr m_providerName = providerName; m_enabled = false; - m_deleteDeferred = false; m_keywords = 0; m_providerLevel = EventPipeEventLevel::Critical; m_pEventList = new SList<SListElem<EventPipeEvent*>>(); @@ -37,8 +36,8 @@ EventPipeProvider::~EventPipeProvider() { CONTRACTL { - NOTHROW; - GC_TRIGGERS; + THROWS; + GC_NOTRIGGER; MODE_ANY; } CONTRACTL_END; @@ -46,30 +45,21 @@ EventPipeProvider::~EventPipeProvider() // Free all of the events. if(m_pEventList != NULL) { - // We swallow exceptions here because the HOST_BREAKABLE - // lock may throw and this destructor gets called in throw - // intolerant places. If that happens the event list will leak - EX_TRY - { - // Take the lock before manipulating the list. - CrstHolder _crst(EventPipe::GetLock()); + // Take the lock before manipulating the list. + CrstHolder _crst(EventPipe::GetLock()); - SListElem<EventPipeEvent*> *pElem = m_pEventList->GetHead(); - while(pElem != NULL) - { - EventPipeEvent *pEvent = pElem->GetValue(); - delete pEvent; - - SListElem<EventPipeEvent*> *pCurElem = pElem; - pElem = m_pEventList->GetNext(pElem); - delete pCurElem; - } + SListElem<EventPipeEvent*> *pElem = m_pEventList->GetHead(); + while(pElem != NULL) + { + EventPipeEvent *pEvent = pElem->GetValue(); + delete pEvent; - delete m_pEventList; + SListElem<EventPipeEvent*> *pCurElem = pElem; + pElem = m_pEventList->GetNext(pElem); + delete pCurElem; } - EX_CATCH { } - EX_END_CATCH(SwallowAllExceptions); + delete m_pEventList; m_pEventList = NULL; } } diff --git a/src/vm/eventpipeprovider.h b/src/vm/eventpipeprovider.h index 0ffe46f887..405ce32154 100644 --- a/src/vm/eventpipeprovider.h +++ b/src/vm/eventpipeprovider.h @@ -31,6 +31,9 @@ class EventPipeProvider friend class SampleProfiler; private: + // The GUID of the provider. + GUID m_providerID; + // The name of the provider. SString m_providerName; diff --git a/src/vm/fastserializer.cpp b/src/vm/fastserializer.cpp index 66fce30793..8e0e0ad768 100644 --- a/src/vm/fastserializer.cpp +++ b/src/vm/fastserializer.cpp @@ -40,7 +40,7 @@ FastSerializer::~FastSerializer() { CONTRACTL { - NOTHROW; + THROWS; GC_TRIGGERS; MODE_ANY; } @@ -98,7 +98,7 @@ void FastSerializer::WriteBuffer(BYTE *pBuffer, unsigned int length) CONTRACTL { NOTHROW; - GC_NOTRIGGER; + GC_TRIGGERS; MODE_PREEMPTIVE; PRECONDITION(pBuffer != NULL); PRECONDITION(length > 0); @@ -263,7 +263,7 @@ void FastSerializer::WriteFileHeader() { CONTRACTL { - NOTHROW; + THROWS; GC_TRIGGERS; MODE_ANY; } @@ -278,7 +278,7 @@ void FastSerializer::WriteString(const char *strContents, unsigned int length) { CONTRACTL { - NOTHROW; + THROWS; GC_TRIGGERS; MODE_PREEMPTIVE; } @@ -295,7 +295,7 @@ StreamLabel FastSerializer::WriteForwardReferenceTable() { CONTRACTL { - NOTHROW; + THROWS; GC_TRIGGERS; MODE_PREEMPTIVE; } @@ -317,7 +317,7 @@ void FastSerializer::WriteTrailer(StreamLabel forwardReferencesTableStart) { CONTRACTL { - NOTHROW; + THROWS; GC_TRIGGERS; MODE_PREEMPTIVE; } diff --git a/src/vm/mscorlib.cpp b/src/vm/mscorlib.cpp index 75c1f058f0..3e2d478bbf 100644 --- a/src/vm/mscorlib.cpp +++ b/src/vm/mscorlib.cpp @@ -96,10 +96,6 @@ #include "eventpipe.h" #endif //defined(FEATURE_EVENTSOURCE_XPLAT) -#ifdef FEATURE_PERFTRACING -#include "eventpipe.h" -#endif //FEATURE_PERFTRACING - #endif // CROSSGEN_MSCORLIB diff --git a/src/vm/sampleprofiler.cpp b/src/vm/sampleprofiler.cpp index ade21669c4..d99667eea2 100644 --- a/src/vm/sampleprofiler.cpp +++ b/src/vm/sampleprofiler.cpp @@ -11,13 +11,6 @@ #ifdef FEATURE_PERFTRACING -#ifndef FEATURE_PAL -#include <mmsystem.h> -#endif //FEATURE_PAL - -// To avoid counting zeros in conversions -#define MILLION * 1000000 - Volatile<BOOL> SampleProfiler::s_profilingEnabled = false; Thread* SampleProfiler::s_pSamplingThread = NULL; const WCHAR* SampleProfiler::s_providerName = W("Microsoft-DotNETCore-SampleProfiler"); @@ -26,16 +19,7 @@ EventPipeEvent* SampleProfiler::s_pThreadTimeEvent = NULL; BYTE* SampleProfiler::s_pPayloadExternal = NULL; BYTE* SampleProfiler::s_pPayloadManaged = NULL; CLREventStatic SampleProfiler::s_threadShutdownEvent; -unsigned long SampleProfiler::s_samplingRateInNs = 1 MILLION; // 1ms -bool SampleProfiler::s_timePeriodIsSet = FALSE; - -#ifndef FEATURE_PAL -PVOID SampleProfiler::s_timeBeginPeriodFn = NULL; -PVOID SampleProfiler::s_timeEndPeriodFn = NULL; -HINSTANCE SampleProfiler::s_hMultimediaLib = NULL; - -typedef MMRESULT (WINAPI *TimePeriodFnPtr) (UINT uPeriod); -#endif //FEATURE_PAL +long SampleProfiler::s_samplingRateInNs = 1000000; // 1ms void SampleProfiler::Enable() { @@ -49,8 +33,6 @@ void SampleProfiler::Enable() PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread()); } CONTRACTL_END; - - LoadDependencies(); if(s_pEventPipeProvider == NULL) { @@ -90,10 +72,6 @@ void SampleProfiler::Enable() { _ASSERT(!"Unable to create sample profiler thread."); } - - s_threadShutdownEvent.CreateManualEvent(FALSE); - - SetTimeGranularity(); } void SampleProfiler::Disable() @@ -123,32 +101,12 @@ void SampleProfiler::Disable() // Wait for the sampling thread to clean itself up. s_threadShutdownEvent.Wait(0, FALSE /* bAlertable */); - - if(s_timePeriodIsSet) - { - ResetTimeGranularity(); - } - UnloadDependencies(); } -void SampleProfiler::SetSamplingRate(unsigned long nanoseconds) +void SampleProfiler::SetSamplingRate(long nanoseconds) { LIMITED_METHOD_CONTRACT; - - // If the time period setting was modified by us, - // make sure to change it back before changing our period - // and losing track of what we set it to - if(s_timePeriodIsSet) - { - ResetTimeGranularity(); - } - s_samplingRateInNs = nanoseconds; - - if(!s_timePeriodIsSet) - { - SetTimeGranularity(); - } } DWORD WINAPI SampleProfiler::ThreadProc(void *args) @@ -174,7 +132,7 @@ DWORD WINAPI SampleProfiler::ThreadProc(void *args) if(ThreadSuspend::SysIsSuspendInProgress() || (ThreadSuspend::GetSuspensionThread() != 0)) { // Skip the current sample. - PlatformSleep(s_samplingRateInNs); + PAL_nanosleep(s_samplingRateInNs); continue; } @@ -188,7 +146,7 @@ DWORD WINAPI SampleProfiler::ThreadProc(void *args) ThreadSuspend::RestartEE(FALSE /* bFinishedGC */, TRUE /* SuspendSucceeded */); // Wait until it's time to sample again. - PlatformSleep(s_samplingRateInNs); + PAL_nanosleep(s_samplingRateInNs); } } @@ -198,7 +156,7 @@ DWORD WINAPI SampleProfiler::ThreadProc(void *args) // Signal Disable() that the thread has been destroyed. s_threadShutdownEvent.Set(); - + return S_OK; } @@ -243,115 +201,4 @@ void SampleProfiler::WalkManagedThreads() } } -void SampleProfiler::PlatformSleep(unsigned long nanoseconds) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - -#ifdef FEATURE_PAL - PAL_nanosleep(nanoseconds); -#else //FEATURE_PAL - ClrSleepEx(s_samplingRateInNs / 1 MILLION, FALSE); -#endif //FEATURE_PAL -} - -void SampleProfiler::SetTimeGranularity() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - -#ifndef FEATURE_PAL - // Attempt to set the systems minimum timer period to the sampling rate - // If the sampling rate is lower than the current system setting (16ms by default), - // this will cause the OS to wake more often for scheduling descsion, allowing us to take samples - // Note that is effects a system-wide setting and when set low will increase the amount of time - // the OS is on-CPU, decreasing overall system performance and increasing power consumption - if(s_timeBeginPeriodFn != NULL) - { - if(((TimePeriodFnPtr) s_timeBeginPeriodFn)(s_samplingRateInNs / 1 MILLION) == TIMERR_NOERROR) - { - s_timePeriodIsSet = TRUE; - } - } -#endif //FEATURE_PAL -} - -void SampleProfiler::ResetTimeGranularity() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - -#ifndef FEATURE_PAL - // End the modifications we had to the timer period in Enable - if(s_timeEndPeriodFn != NULL) - { - if(((TimePeriodFnPtr) s_timeEndPeriodFn)(s_samplingRateInNs / 1 MILLION) == TIMERR_NOERROR) - { - s_timePeriodIsSet = FALSE; - } - } -#endif //FEATURE_PAL -} - -bool SampleProfiler::LoadDependencies() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - -#ifndef FEATURE_PAL - s_hMultimediaLib = WszLoadLibrary(W("winmm.dll")); - - if (s_hMultimediaLib != NULL) - { - s_timeBeginPeriodFn = (PVOID) GetProcAddress(s_hMultimediaLib, "timeBeginPeriod"); - s_timeEndPeriodFn = (PVOID) GetProcAddress(s_hMultimediaLib, "timeEndPeriod"); - } - - return s_hMultimediaLib != NULL && s_timeBeginPeriodFn != NULL && s_timeEndPeriodFn != NULL; -#else - return FALSE; -#endif //FEATURE_PAL -} - -void SampleProfiler::UnloadDependencies() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - -#ifndef FEATURE_PAL - if (s_hMultimediaLib != NULL) - { - FreeLibrary(s_hMultimediaLib); - s_hMultimediaLib = NULL; - s_timeBeginPeriodFn = NULL; - s_timeEndPeriodFn = NULL; - } -#endif //FEATURE_PAL -} - #endif // FEATURE_PERFTRACING diff --git a/src/vm/sampleprofiler.h b/src/vm/sampleprofiler.h index 1bee70e8f6..51290b4d9c 100644 --- a/src/vm/sampleprofiler.h +++ b/src/vm/sampleprofiler.h @@ -33,7 +33,7 @@ class SampleProfiler static void Disable(); // Set the sampling rate. - static void SetSamplingRate(unsigned long nanoseconds); + static void SetSamplingRate(long nanoseconds); private: @@ -43,31 +43,6 @@ class SampleProfiler // Profiling thread proc. Invoked on a new thread when profiling is enabled. static DWORD WINAPI ThreadProc(void *args); - // Calls either PAL_nanosleep or ClrSleepEx depending on platform - // Note: Although we specify the time in ns, that is no indication - // of the actually accuracy with which we will return from sleep - // In reality Unix will have a minimum granularity of ~10ms - // and Windows has a default granularity of ~16ms, but can be - // adjusted to as low as ~1ms - // Even this however is not gaurenteed. If the system is under load - // the sampling thread may be delayed up to hundreds of ms due to - // scheduling priority. There is no way to prevent this from user threads - // Additionally we may get lucky and there will be an open CPU to run - // and under light load the timings will achieve great accuracy! - static void PlatformSleep(unsigned long nanoseconds); - - static bool LoadDependencies(); - static void UnloadDependencies(); - -#ifndef FEATURE_PAL - static HINSTANCE s_hMultimediaLib; - static PVOID s_timeBeginPeriodFn; - static PVOID s_timeEndPeriodFn; -#endif //FEATURE_PAL - - static void SetTimeGranularity(); - static void ResetTimeGranularity(); - // True when profiling is enabled. static Volatile<BOOL> s_profilingEnabled; @@ -90,10 +65,7 @@ class SampleProfiler static CLREventStatic s_threadShutdownEvent; // The sampling rate. - static unsigned long s_samplingRateInNs; - - // Whether or not timeBeginPeriod has been used to set the scheduler period - static bool s_timePeriodIsSet; + static long s_samplingRateInNs; }; #endif // FEATURE_PERFTRACING diff --git a/tests/runtest.proj b/tests/runtest.proj index 3ab7b9f708..9c12e275d7 100644 --- a/tests/runtest.proj +++ b/tests/runtest.proj @@ -12,6 +12,7 @@ <ItemGroup> <DisabledTestDir Include="Common" /> + <DisabledTestDir Include="tracing" /> <_SkipTestDir Include="@(DisabledTestDir)" /> </ItemGroup> @@ -403,4 +404,4 @@ namespace $([System.String]::Copy($(Category)).Replace(".","_").Replace("\",""). <Target Name="Clean"> <RemoveDir Condition=" '$(BuildWrappers)'=='true'" Directories="$(XunitWrapperGeneratedCSDirBase);$(XunitWrapperOutputIntermediatedDirBase)" ContinueOnError="WarnAndContinue" /> </Target> -</Project> +</Project>
\ No newline at end of file diff --git a/tests/src/JIT/config/benchmark+roslyn/benchmark+roslyn.csproj b/tests/src/JIT/config/benchmark+roslyn/benchmark+roslyn.csproj index 563a9a7087..77cba12414 100644 --- a/tests/src/JIT/config/benchmark+roslyn/benchmark+roslyn.csproj +++ b/tests/src/JIT/config/benchmark+roslyn/benchmark+roslyn.csproj @@ -67,9 +67,6 @@ <PackageReference Include="System.Threading"> <Version>4.4.0-beta-24913-02</Version> </PackageReference> - <PackageReference Include="System.Threading.Thread"> - <Version>4.4.0-beta-24913-02</Version> - </PackageReference> <PackageReference Include="System.Threading.Tasks"> <Version>4.4.0-beta-24913-02</Version> </PackageReference> diff --git a/tests/src/JIT/config/benchmark/benchmark.csproj b/tests/src/JIT/config/benchmark/benchmark.csproj index 4d49fdee3e..5ade686330 100644 --- a/tests/src/JIT/config/benchmark/benchmark.csproj +++ b/tests/src/JIT/config/benchmark/benchmark.csproj @@ -76,9 +76,6 @@ <PackageReference Include="System.Threading"> <Version>4.4.0-beta-24913-02</Version> </PackageReference> - <PackageReference Include="System.Threading.Thread"> - <Version>4.4.0-beta-24913-02</Version> - </PackageReference> <PackageReference Include="System.Threading.Tasks"> <Version>4.4.0-beta-24913-02</Version> </PackageReference> diff --git a/tests/src/dirs.proj b/tests/src/dirs.proj index 543935f752..471598d82d 100644 --- a/tests/src/dirs.proj +++ b/tests/src/dirs.proj @@ -30,7 +30,6 @@ <DisabledProjects Include="Performance\performance.csproj" /> <DisabledProjects Include="Loader\classloader\generics\regressions\DD117522\Test.csproj" /> <DisabledProjects Include="Loader\classloader\generics\GenericMethods\VSW491668.csproj" /> <!-- issue 5501 --> - <DisabledProjects Include="tracing\eventsource*" /> </ItemGroup> <ItemGroup> diff --git a/tests/src/performance/performance.csproj b/tests/src/performance/performance.csproj index 94caf35ac2..8c2cd3c7de 100644 --- a/tests/src/performance/performance.csproj +++ b/tests/src/performance/performance.csproj @@ -70,9 +70,6 @@ <PackageReference Include="System.Threading"> <Version>4.4.0-beta-24913-02</Version> </PackageReference> - <PackageReference Include="System.Threading.Thread"> - <Version>4.4.0-beta-24913-02</Version> - </PackageReference> <PackageReference Include="System.Threading.Tasks"> <Version>4.4.0-beta-24913-02</Version> </PackageReference> diff --git a/tests/src/tracing/common/common.csproj b/tests/src/tracing/common/common.csproj index ca10e7ffe2..ca34349b16 100644 --- a/tests/src/tracing/common/common.csproj +++ b/tests/src/tracing/common/common.csproj @@ -12,7 +12,7 @@ <CLRTestKind>BuildOnly</CLRTestKind> <DefineConstants>$(DefineConstants);STATIC</DefineConstants> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - <CLRTestPriority>0</CLRTestPriority> + <CLRTestPriority>1</CLRTestPriority> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> diff --git a/tests/src/tracing/eventpipesmoke/EventPipeSmoke.cs b/tests/src/tracing/eventpipesmoke/EventPipeSmoke.cs index 2fa8786fd2..c12893d38a 100644 --- a/tests/src/tracing/eventpipesmoke/EventPipeSmoke.cs +++ b/tests/src/tracing/eventpipesmoke/EventPipeSmoke.cs @@ -1,5 +1,7 @@ using System; +using System.Threading.Tasks; using System.IO; + using Tracing.Tests.Common; namespace Tracing.Tests diff --git a/tests/src/tracing/eventpipesmoke/eventpipesmoke.csproj b/tests/src/tracing/eventpipesmoke/eventpipesmoke.csproj index 4a1cd0c0ce..8ba6eb5c4a 100644 --- a/tests/src/tracing/eventpipesmoke/eventpipesmoke.csproj +++ b/tests/src/tracing/eventpipesmoke/eventpipesmoke.csproj @@ -12,7 +12,7 @@ <CLRTestKind>BuildAndRun</CLRTestKind> <DefineConstants>$(DefineConstants);STATIC</DefineConstants> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - <CLRTestPriority>0</CLRTestPriority> + <CLRTestPriority>1</CLRTestPriority> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup> diff --git a/tests/src/tracing/eventpipetrace/EventPipeTrace.cs b/tests/src/tracing/eventpipetrace/EventPipeTrace.cs deleted file mode 100644 index af0c619ef9..0000000000 --- a/tests/src/tracing/eventpipetrace/EventPipeTrace.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.IO; -using Tracing.Tests.Common; -using Microsoft.Diagnostics.Tracing; -using Microsoft.Diagnostics.Tracing.Parsers; -using Microsoft.Diagnostics.Tracing.Parsers.Clr; - -namespace Tracing.Tests -{ - class EventPipeTrace - { - private static int allocIterations = 10000; - private static int gcIterations = 10; - - static void AssertEqual<T>(T left, T right) where T : IEquatable<T> - { - if (left.Equals(right) == false) - { - throw new Exception(string.Format("Values were not equal! {0} and {1}", left, right)); - } - } - - static int Main(string[] args) - { - bool pass = true; - bool keepOutput = false; - - // Use the first arg as an output filename if there is one - string outputFilename = null; - if (args.Length >= 1) { - outputFilename = args[0]; - keepOutput = true; - } - else { - outputFilename = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".netperf"; - } - - try - { - Console.WriteLine("\tStart: Enable tracing."); - TraceControl.EnableDefault(outputFilename); - Console.WriteLine("\tEnd: Enable tracing.\n"); - - Console.WriteLine("\tStart: Generating CLR events"); - // Allocate for allocIterations iterations. - for(int i=0; i<allocIterations; i++) - { - GC.KeepAlive(new object()); - } - // GC gcIternation times - for(int i=0; i<gcIterations; i++) - { - GC.Collect(); - } - Console.WriteLine("\tEnd: Generating CLR Events\n"); - - Console.WriteLine("\tStart: Disable tracing."); - TraceControl.Disable(); - Console.WriteLine("\tEnd: Disable tracing.\n"); - - Console.WriteLine("\tStart: Processing events from file."); - int allocTickCount = 0; - int gcTriggerCount = 0; - using (var trace = TraceEventDispatcher.GetDispatcherFromFileName(outputFilename)) - { - trace.Clr.GCAllocationTick += delegate(GCAllocationTickTraceData data) - { - allocTickCount += 1; - - // Some basic integrity checks - // AssertEqual(data.TypeName, "System.Object"); https://github.com/Microsoft/perfview/issues/470 - AssertEqual(data.AllocationKind.ToString(), GCAllocationKind.Small.ToString()); - AssertEqual(data.ProviderName, "Microsoft-Windows-DotNETRuntime"); - AssertEqual(data.EventName, "GC/AllocationTick"); - }; - trace.Clr.GCTriggered += delegate(GCTriggeredTraceData data) - { - gcTriggerCount += 1; - - // Some basic integrity checks - AssertEqual(data.Reason.ToString(), GCReason.Induced.ToString()); - AssertEqual(data.ProviderName, "Microsoft-Windows-DotNETRuntime"); - AssertEqual(data.EventName, "GC/Triggered"); - }; - - trace.Process(); - } - Console.WriteLine("\tEnd: Processing events from file.\n"); - - Console.WriteLine("\tProcessed {0} GCAllocationTick events", allocTickCount); - Console.WriteLine("\tProcessed {0} GCTriggered events", gcTriggerCount); - - pass &= allocTickCount > 0; - pass &= gcTriggerCount == gcIterations; - } - finally { - if (keepOutput) - { - Console.WriteLine("\n\tOutput file: {0}", outputFilename); - } - else - { - System.IO.File.Delete(outputFilename); - } - } - - return pass ? 100 : 0; - } - } -} diff --git a/tests/src/tracing/eventpipetrace/eventpipetrace.csproj b/tests/src/tracing/eventpipetrace/eventpipetrace.csproj deleted file mode 100644 index ec7305abe9..0000000000 --- a/tests/src/tracing/eventpipetrace/eventpipetrace.csproj +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> - <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <SchemaVersion>2.0</SchemaVersion> - <ProjectGuid>{8E3244CB-407F-4142-BAAB-E7A55901A5FA}</ProjectGuid> - <OutputType>Exe</OutputType> - <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> - <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> - <CLRTestKind>BuildAndRun</CLRTestKind> - <DefineConstants>$(DefineConstants);STATIC</DefineConstants> - <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - <CLRTestPriority>0</CLRTestPriority> - </PropertyGroup> - <!-- Default configurations to help VS understand the configurations --> - <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"></PropertyGroup> - <ItemGroup> - <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> - <Visible>False</Visible> - </CodeAnalysisDependentAssemblyPaths> - </ItemGroup> - <ItemGroup> - <Compile Include="EventPipeTrace.cs" /> - <ProjectReference Include="../common/common.csproj" /> - </ItemGroup> - <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> -</Project>
\ No newline at end of file diff --git a/tests/src/tracing/eventsourcesmoke/EventSourceSmoke.cs b/tests/src/tracing/eventsourcesmoke/EventSourceSmoke.cs index ddd5192e18..b7d321dde6 100644 --- a/tests/src/tracing/eventsourcesmoke/EventSourceSmoke.cs +++ b/tests/src/tracing/eventsourcesmoke/EventSourceSmoke.cs @@ -1,6 +1,8 @@ using System; +using System.Threading.Tasks; using System.IO; using System.Diagnostics.Tracing; + using Tracing.Tests.Common; namespace Tracing.Tests diff --git a/tests/src/tracing/eventsourcetrace/EventSourceTrace.cs b/tests/src/tracing/eventsourcetrace/EventSourceTrace.cs deleted file mode 100644 index 57a53183ed..0000000000 --- a/tests/src/tracing/eventsourcetrace/EventSourceTrace.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using System.IO; -using System.Collections.Generic; -using Tracing.Tests.Common; -using System.Diagnostics.Tracing; -using Microsoft.Diagnostics.Tracing; -using Microsoft.Diagnostics.Tracing.Parsers; -using Microsoft.Diagnostics.Tracing.Parsers.Clr; - -namespace Tracing.Tests -{ - [EventSource(Name = "SimpleEventSource")] - class SimpleEventSource : EventSource - { - public SimpleEventSource() : base(true) { } - - [Event(1)] - internal void MathResult(int x, int y, int z, string formula) { this.WriteEvent(1, x, y, z, formula); } - } - - class EventSourceTrace - { - private static int messageIterations = 10000; - - public static TraceConfiguration GetConfig(EventSource eventSource, string outputFile="default.netperf") - { - // Setup the configuration values. - uint circularBufferMB = 1024; // 1 GB - uint level = 5;//(uint)EventLevel.Informational; - TimeSpan profSampleDelay = TimeSpan.FromMilliseconds(1); - - // Create a new instance of EventPipeConfiguration. - TraceConfiguration config = new TraceConfiguration(outputFile, circularBufferMB); - // Setup the provider values. - // Public provider. - string providerName = eventSource.Name; - UInt64 keywords = 0xffffffffffffffff; - - // Enable the provider. - config.EnableProvider(providerName, keywords, level); - - // Set the sampling rate. - config.SetSamplingRate(profSampleDelay); - - return config; - } - - static int Main(string[] args) - { - bool pass = true; - bool keepOutput = false; - - // Use the first arg as an output filename if there is one - string outputFilename = null; - if (args.Length >= 1) { - outputFilename = args[0]; - keepOutput = true; - } - else { - outputFilename = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".netperf"; - } - - SimpleEventSource eventSource = new SimpleEventSource(); - - try - { - Console.WriteLine("\tStart: Enable tracing."); - TraceControl.Enable(GetConfig(eventSource, outputFilename)); - Console.WriteLine("\tEnd: Enable tracing.\n"); - - Console.WriteLine("\tStart: Messaging."); - // Send messages - // Use random numbers and addition as a simple, human readble checksum - Random generator = new Random(); - for(int i=0; i<messageIterations; i++) - { - int x = generator.Next(1,1000); - int y = generator.Next(1,1000); - string formula = String.Format("{0} + {1} = {2}", x, y, x+y); - - eventSource.MathResult(x, y, x+y, formula); - } - Console.WriteLine("\tEnd: Messaging.\n"); - - Console.WriteLine("\tStart: Disable tracing."); - TraceControl.Disable(); - Console.WriteLine("\tEnd: Disable tracing.\n"); - - Console.WriteLine("\tStart: Processing events from file."); - int msgCount = 0; - using (var trace = TraceEventDispatcher.GetDispatcherFromFileName(outputFilename)) - { - var names = new HashSet<string>(); - - trace.Dynamic.All += delegate(TraceEvent data) - { - if (!names.Contains(data.ProviderName)) - { - Console.WriteLine("\t{0}", data.ProviderName); - names.Add(data.ProviderName); - } - - if (data.ProviderName == "SimpleEventSource") - { - msgCount += 1; - } - }; - - trace.Process(); - } - Console.WriteLine("\tEnd: Processing events from file.\n"); - - Console.WriteLine("\tProcessed {0} events from EventSource", msgCount); - - pass &= msgCount == messageIterations; - } - finally { - if (keepOutput) - { - Console.WriteLine("\n\tOutput file: {0}", outputFilename); - } - else - { - System.IO.File.Delete(outputFilename); - } - } - - return pass ? 100 : 0; - } - } -} diff --git a/tests/src/tracing/eventsourcetrace/eventsourcetrace.csproj b/tests/src/tracing/eventsourcetrace/eventsourcetrace.csproj deleted file mode 100644 index 833146ec64..0000000000 --- a/tests/src/tracing/eventsourcetrace/eventsourcetrace.csproj +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> - <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <SchemaVersion>2.0</SchemaVersion> - <ProjectGuid>{8E3244CB-407F-4142-BAAB-E7A55901A5FA}</ProjectGuid> - <OutputType>Exe</OutputType> - <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> - <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> - <CLRTestKind>BuildAndRun</CLRTestKind> - <DefineConstants>$(DefineConstants);STATIC</DefineConstants> - <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - <CLRTestPriority>1</CLRTestPriority> - </PropertyGroup> - <!-- Default configurations to help VS understand the configurations --> - <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"></PropertyGroup> - <ItemGroup> - <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies"> - <Visible>False</Visible> - </CodeAnalysisDependentAssemblyPaths> - </ItemGroup> - <ItemGroup> - <Compile Include="EventSourceTrace.cs" /> - <ProjectReference Include="../common/common.csproj" /> - </ItemGroup> - <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> -</Project>
\ No newline at end of file |