summaryrefslogtreecommitdiff
path: root/src/scripts
diff options
context:
space:
mode:
authorVictor "Nate" Graf <nategraf1@gmail.com>2017-12-21 11:48:14 -0800
committerGitHub <noreply@github.com>2017-12-21 11:48:14 -0800
commit302005ca8ae14eade37ddf4ac6e900617c1c166a (patch)
treedf32e188ca3c3c2bec14d61b477e54dd4b2fe0c8 /src/scripts
parent0e4662c8911e3cf80eaaa446f280d7694ac09733 (diff)
downloadcoreclr-302005ca8ae14eade37ddf4ac6e900617c1c166a.tar.gz
coreclr-302005ca8ae14eade37ddf4ac6e900617c1c166a.tar.bz2
coreclr-302005ca8ae14eade37ddf4ac6e900617c1c166a.zip
Revert "Enable EventPipe across Unix and Windows (#14772)" (#15609)
This reverts commit 7524d72d4f0f634fe5407280b83c25181dc8c556.
Diffstat (limited to 'src/scripts')
-rw-r--r--src/scripts/Utilities.py49
-rw-r--r--src/scripts/check-definitions.py24
-rw-r--r--src/scripts/genDummyProvider.py211
-rw-r--r--src/scripts/genEtwProvider.py312
-rw-r--r--src/scripts/genEventPipe.py313
-rw-r--r--src/scripts/genWinEtw.py125
-rw-r--r--src/scripts/genXplatEventing.py (renamed from src/scripts/genEventing.py)387
-rw-r--r--src/scripts/genXplatLttng.py (renamed from src/scripts/genLttngProvider.py)228
-rw-r--r--src/scripts/utilities.py106
9 files changed, 673 insertions, 1082 deletions
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)