def main(argv): # parse the command line parser = argparse.ArgumentParser( description="Generates the Code required to instrument eventpipe 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') 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('--dry-run', action='store_true', help='if specified, will output the names of the generated files instead of generating the files' ) args, unknown = parser.parse_known_args(argv) if unknown: print('Unknown argument(s): ', ', '.join(unknown)) return 1 sClrEtwAllMan = args.man exclusion_filename = args.exc intermediate = args.intermediate extern = not args.nonextern dryRun = args.dry_run generateEventPipeFiles(sClrEtwAllMan, intermediate, extern, parseExclusionList(exclusion_filename), dryRun)
def main(argv): # parse the command line parser = argparse.ArgumentParser( description="Generates the Code required to instrument eventpipe 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') required.add_argument('--nonextern', action='store_true', help='if specified, will generate files to be compiled into the CLR rather than extern' ) args, unknown = parser.parse_known_args(argv) if unknown: print('Unknown argument(s): ', ', '.join(unknown)) return 1 sClrEtwAllMan = args.man exclusion_filename = args.exc intermediate = args.intermediate extern = not args.nonextern generateEventPipeFiles(sClrEtwAllMan, intermediate, extern, parseExclusionList(exclusion_filename))
def genEtwMacroHeader(manifest, exclusion_filename, intermediate): provider_dirname = os.path.join(intermediate, etw_dirname + "_temp") 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 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 genEtwMacroHeader(manifest, exclusion_filename, intermediate): provider_dirname = os.path.join(intermediate, etw_dirname + "_temp") 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 constexpr 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 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)