def generatePlatformIndependentFiles(sClrEtwAllMan, incDir, etmDummyFile, extern, write_xplatheader): generateEtmDummyHeader(sClrEtwAllMan,etmDummyFile) tree = DOM.parse(sClrEtwAllMan) if not incDir: return print(' Generating Event Headers') 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" """) 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") clreventpipewriteevents = os.path.join(incDir, "clreventpipewriteevents.h") with open_for_update(clreventpipewriteevents) as Clreventpipewriteevents: Clreventpipewriteevents.write(stdprolog + "\n") for providerNode in tree.getElementsByTagName('provider'): templateNodes = providerNode.getElementsByTagName('template') allTemplates = parseTemplateNodes(templateNodes) eventNodes = providerNode.getElementsByTagName('event') #eventpipe: create clreventpipewriteevents.h Clreventpipewriteevents.write(generateClrEventPipeWriteEvents(eventNodes, allTemplates, extern) + "\n") # Write secondary headers for FireEtXplat* and EventPipe* functions if write_xplatheader: clrxplatevents = os.path.join(incDir, "clrxplatevents.h") with open_for_update(clrxplatevents) as Clrxplatevents: Clrxplatevents.write(stdprolog + "\n") for providerNode in tree.getElementsByTagName('provider'): templateNodes = providerNode.getElementsByTagName('template') allTemplates = parseTemplateNodes(templateNodes) eventNodes = providerNode.getElementsByTagName('event') #pal: create clrallevents.h Clrxplatevents.write(generateClrXplatEvents(eventNodes, allTemplates, extern) + "\n")
def generateEventPipeCmakeFile(etwmanifest, eventpipe_directory, extern): 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(""" set(CMAKE_INCLUDE_CURRENT_DIR ON) include_directories(${CLR_DIR}/src/vm) add_library_clr(eventpipe STATIC """) for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerName = providerName.replace("Windows-", '') providerName = providerName.replace("Microsoft-", '') 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(""" # Install the static eventpipe library _install(TARGETS eventpipe DESTINATION lib) """)
def generateEventPipeCmakeFile(etwmanifest, eventpipe_directory, extern): 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(""" set(CMAKE_INCLUDE_CURRENT_DIR ON) include_directories(${CLR_DIR}/src/vm) """) if extern: cmake_file.write("add_library") else: cmake_file.write("add_library_clr") cmake_file.write("""(eventpipe STATIC\n""") for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerName = providerName.replace("Windows-", '') providerName = providerName.replace("Microsoft-", '') 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(""" # Install the static eventpipe library install(TARGETS eventpipe DESTINATION lib) """)
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 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))
def generateDummyFiles(etwmanifest, out_dirname, runtimeFlavor, extern, dryRun): 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)) # 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") if dryRun: print(dummyevntprov) else: with open_for_update(dummyevntprov) as impl: impl.write(stdprolog_cpp + "\n") impl.write(""" #ifdef TARGET_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, runtimeFlavor, extern) + "\n")
def generateEventPipeHelperFile(etwmanifest, eventpipe_directory, target_cpp, runtimeFlavor, extern, dryRun): eventpipehelpersPath = os.path.join( eventpipe_directory, "eventpipehelpers" + (".cpp" if target_cpp else ".c")) if dryRun: print(eventpipehelpersPath) else: with open_for_update(eventpipehelpersPath) as helper: helper.write(stdprolog_cpp) if runtimeFlavor.coreclr: helper.write(getCoreCLREventPipeHelperFileImplPrefix()) elif runtimeFlavor.mono: helper.write(getMonoEventPipeHelperFileImplPrefix()) tree = DOM.parse(etwmanifest) for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') if includeProvider(providerName, runtimeFlavor): providerPrettyName = providerName.replace("Windows-", '') providerPrettyName = providerPrettyName.replace( "Microsoft-", '') providerPrettyName = providerPrettyName.replace('-', '_') if extern: helper.write('extern "C" ') helper.write("void Init" + providerPrettyName + "(void);\n\n") if extern: helper.write('extern "C" ') helper.write("void InitProvidersAndEvents(void);\n\n") helper.write("void InitProvidersAndEvents(void)\n{\n") for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') if includeProvider(providerName, runtimeFlavor): providerPrettyName = providerName.replace("Windows-", '') providerPrettyName = providerPrettyName.replace( "Microsoft-", '') providerPrettyName = providerPrettyName.replace('-', '_') helper.write(" Init" + providerPrettyName + "();\n") helper.write("}\n") if runtimeFlavor.coreclr: helper.write(getCoreCLREventPipeHelperFileImplSuffix()) elif runtimeFlavor.mono: helper.write(getMonoEventPipeHelperFileImplSuffix()) helper.close()
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 generateEtmDummyHeader(sClrEtwAllMan,clretwdummy): if not clretwdummy: return tree = DOM.parse(sClrEtwAllMan) incDir = os.path.dirname(os.path.realpath(clretwdummy)) if not os.path.exists(incDir): os.makedirs(incDir) with open_for_update(clretwdummy) as Clretwdummy: 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")
def generateEtmDummyHeader(sClrEtwAllMan,clretwdummy): if not clretwdummy: return print(' Generating Dummy Event Headers') tree = DOM.parse(sClrEtwAllMan) incDir = os.path.dirname(os.path.realpath(clretwdummy)) if not os.path.exists(incDir): os.makedirs(incDir) with open_for_update(clretwdummy) as Clretwdummy: 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")
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 generateLttngFiles(etwmanifest, eventprovider_directory, dryRun): eventprovider_directory = eventprovider_directory + "/" tree = DOM.parse(etwmanifest) #keep these relative tracepointprovider_directory = "tracepointprovider" lttng_directory = "lttng" lttngevntprovPre = lttng_directory + "/eventprov" lttngevntprovTpPre = lttng_directory + "/traceptprov" if not os.path.exists(eventprovider_directory): os.makedirs(eventprovider_directory) if not os.path.exists(eventprovider_directory + lttng_directory): os.makedirs(eventprovider_directory + lttng_directory) if not os.path.exists(eventprovider_directory + tracepointprovider_directory): os.makedirs(eventprovider_directory + tracepointprovider_directory) # Generate Lttng specific instrumentation for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerName = providerName.replace("Windows-", '') providerName = providerName.replace("Microsoft-", '') providerName_File = providerName.replace('-', '') providerName_File = providerName_File.lower() providerName = providerName.replace('-', '_') 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) if dryRun: print(lttngevntheader) print(lttngevntprov) print(lttngevntprovTp) else: with open_for_update(lttngevntheader) as lttnghdr_file: lttnghdr_file.write(stdprolog + "\n") lttnghdr_file.write(""" #include "palrt.h" #include "pal.h" #undef TRACEPOINT_PROVIDER """) lttnghdr_file.write("#define TRACEPOINT_PROVIDER " + providerName + "\n") lttnghdr_file.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_file.write("\n#include <lttng/tracepoint.h>\n\n") lttnghdr_file.write( generateLttngHeader(providerName, allTemplates, eventNodes) + "\n") with open_for_update(lttngevntprov) as lttngimpl_file: lttngimpl_file.write(stdprolog + "\n") lttngimpl_file.write(""" #define TRACEPOINT_DEFINE #define TRACEPOINT_PROBE_DYNAMIC_LINKAGE #include "stdlib.h" #include "pal_mstypes.h" #include "pal_error.h" #include "pal.h" #define PAL_free free #define PAL_realloc realloc #include "pal/stackstring.hpp" """) lttngimpl_file.write("#include \"" + lttngevntheadershortname + "\"\n\n") lttngimpl_file.write("""#ifndef tracepoint_enabled extern "C" bool XplatEventLoggerIsEnabled(); #define tracepoint_enabled(provider, name) XplatEventLoggerIsEnabled() #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); template <typename T> bool WriteToBuffer(const T &value, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) { if (sizeof(T) + offset > size) { if (!ResizeBuffer(buffer, size, offset, size + sizeof(T), fixedBuffer)) return false; } memcpy(buffer + offset, (char *)&value, sizeof(T)); 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") tpimpl_file.write("\n#define TRACEPOINT_CREATE_PROBES\n") tpimpl_file.write("#include \"./" + lttngevntheadershortname + "\"\n")
def generatePlatformIndependentFiles(sClrEtwAllMan, incDir, etmDummyFile, extern, write_xplatheader): generateEtmDummyHeader(sClrEtwAllMan, etmDummyFile) tree = DOM.parse(sClrEtwAllMan) if not incDir: return if not os.path.exists(incDir): os.makedirs(incDir) eventpipe_trace_context_typedef = """ #if !defined(EVENTPIPE_TRACE_CONTEXT_DEF) #define EVENTPIPE_TRACE_CONTEXT_DEF typedef struct _EVENTPIPE_TRACE_CONTEXT { WCHAR const * Name; UCHAR Level; bool IsEnabled; ULONGLONG EnabledKeywordsBitmask; } EVENTPIPE_TRACE_CONTEXT, *PEVENTPIPE_TRACE_CONTEXT; #endif // EVENTPIPE_TRACE_CONTEXT_DEF """ lttng_trace_context_typedef = """ #if !defined(LTTNG_TRACE_CONTEXT_DEF) #define LTTNG_TRACE_CONTEXT_DEF typedef struct _LTTNG_TRACE_CONTEXT { WCHAR const * Name; UCHAR Level; bool IsEnabled; ULONGLONG EnabledKeywordsBitmask; } LTTNG_TRACE_CONTEXT, *PLTTNG_TRACE_CONTEXT; #endif // LTTNG_TRACE_CONTEXT_DEF """ dotnet_trace_context_typedef_windows = """ #if !defined(DOTNET_TRACE_CONTEXT_DEF) #define DOTNET_TRACE_CONTEXT_DEF typedef struct _DOTNET_TRACE_CONTEXT { PMCGEN_TRACE_CONTEXT EtwProvider; EVENTPIPE_TRACE_CONTEXT EventPipeProvider; } DOTNET_TRACE_CONTEXT, *PDOTNET_TRACE_CONTEXT; #endif // DOTNET_TRACE_CONTEXT_DEF """ dotnet_trace_context_typedef_unix = """ #if !defined(DOTNET_TRACE_CONTEXT_DEF) #define DOTNET_TRACE_CONTEXT_DEF typedef struct _DOTNET_TRACE_CONTEXT { EVENTPIPE_TRACE_CONTEXT EventPipeProvider; PLTTNG_TRACE_CONTEXT LttngProvider; } DOTNET_TRACE_CONTEXT, *PDOTNET_TRACE_CONTEXT; #endif // DOTNET_TRACE_CONTEXT_DEF """ # Write the main header for FireETW* functions clrallevents = os.path.join(incDir, "clretwallmain.h") is_windows = os.name == 'nt' with open_for_update(clrallevents) as Clrallevents: Clrallevents.write(stdprolog) Clrallevents.write(""" #include "clrxplatevents.h" #include "clreventpipewriteevents.h" """) # define DOTNET_TRACE_CONTEXT depending on the platform if is_windows: Clrallevents.write(eventpipe_trace_context_typedef ) # define EVENTPIPE_TRACE_CONTEXT Clrallevents.write(dotnet_trace_context_typedef_windows) 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") providerName = providerNode.getAttribute('name') providerSymbol = providerNode.getAttribute('symbol') if is_windows: eventpipeProviderCtxName = providerSymbol + "_EVENTPIPE_Context" Clrallevents.write('SELECTANY EVENTPIPE_TRACE_CONTEXT const ' + eventpipeProviderCtxName + ' = { W("' + providerName + '"), 0, false, 0 };\n') if write_xplatheader: clrproviders = os.path.join(incDir, "clrproviders.h") with open_for_update(clrproviders) as Clrproviders: Clrproviders.write(""" typedef struct _EVENT_DESCRIPTOR { int const Level; ULONGLONG const Keyword; } EVENT_DESCRIPTOR;""") if not is_windows: Clrproviders.write(eventpipe_trace_context_typedef ) # define EVENTPIPE_TRACE_CONTEXT Clrproviders.write( lttng_trace_context_typedef) # define LTTNG_TRACE_CONTEXT Clrproviders.write(dotnet_trace_context_typedef_unix) allProviders = [] nbProviders = 0 for providerNode in tree.getElementsByTagName('provider'): keywords = [] keywordsToMask = {} providerName = str(providerNode.getAttribute('name')) providerSymbol = str(providerNode.getAttribute('symbol')) nbProviders += 1 nbKeywords = 0 if not is_windows: eventpipeProviderCtxName = providerSymbol + "_EVENTPIPE_Context" Clrproviders.write( '__attribute__((weak)) EVENTPIPE_TRACE_CONTEXT ' + eventpipeProviderCtxName + ' = { W("' + providerName + '"), 0, false, 0 };\n') lttngProviderCtxName = providerSymbol + "_LTTNG_Context" Clrproviders.write( '__attribute__((weak)) LTTNG_TRACE_CONTEXT ' + lttngProviderCtxName + ' = { W("' + providerName + '"), 0, false, 0 };\n') Clrproviders.write("// Keywords\n") for keywordNode in providerNode.getElementsByTagName( 'keyword'): keywordName = keywordNode.getAttribute('name') keywordMask = keywordNode.getAttribute('mask') keywordSymbol = keywordNode.getAttribute('symbol') Clrproviders.write("#define " + keywordSymbol + " " + keywordMask + "\n") keywords.append("{ \"" + keywordName + "\", " + keywordMask + " }") keywordsToMask[keywordName] = int(keywordMask, 16) nbKeywords += 1 for eventNode in providerNode.getElementsByTagName('event'): levelName = eventNode.getAttribute('level') symbolName = eventNode.getAttribute('symbol') keywords = eventNode.getAttribute('keywords') level = convertToLevelId(levelName) Clrproviders.write( "SELECTANY EVENT_DESCRIPTOR const " + symbolName + " = { " + str(level) + ", " + hex(getKeywordsMaskCombined(keywords, keywordsToMask)) + " };\n") allProviders.append("&" + providerSymbol + "_LTTNG_Context") # define and initialize runtime providers' DOTNET_TRACE_CONTEXT depending on the platform if not is_windows: Clrproviders.write('#define NB_PROVIDERS ' + str(nbProviders) + '\n') Clrproviders.write( 'SELECTANY LTTNG_TRACE_CONTEXT * const ALL_LTTNG_PROVIDERS_CONTEXT[NB_PROVIDERS] = { ' ) Clrproviders.write(', '.join(allProviders)) Clrproviders.write(' };\n') clreventpipewriteevents = os.path.join(incDir, "clreventpipewriteevents.h") with open_for_update(clreventpipewriteevents) as Clreventpipewriteevents: Clreventpipewriteevents.write(stdprolog + "\n") for providerNode in tree.getElementsByTagName('provider'): templateNodes = providerNode.getElementsByTagName('template') allTemplates = parseTemplateNodes(templateNodes) eventNodes = providerNode.getElementsByTagName('event') #eventpipe: create clreventpipewriteevents.h Clreventpipewriteevents.write( generateClrEventPipeWriteEvents(eventNodes, allTemplates, extern) + "\n") # Write secondary headers for FireEtXplat* and EventPipe* functions if write_xplatheader: clrxplatevents = os.path.join(incDir, "clrxplatevents.h") with open_for_update(clrxplatevents) as Clrxplatevents: Clrxplatevents.write(stdprolog + "\n") for providerNode in tree.getElementsByTagName('provider'): templateNodes = providerNode.getElementsByTagName('template') allTemplates = parseTemplateNodes(templateNodes) eventNodes = providerNode.getElementsByTagName('event') #pal: create clrallevents.h Clrxplatevents.write( generateClrXplatEvents(eventNodes, allTemplates, extern) + "\n")
def generateLttngFiles(etwmanifest,eventprovider_directory): eventprovider_directory = eventprovider_directory + "/" tree = DOM.parse(etwmanifest) #keep these relative tracepointprovider_directory = "tracepointprovider" lttng_directory = "lttng" lttngevntprovPre = lttng_directory + "/eventprov" lttngevntprovTpPre = lttng_directory + "/traceptprov" if not os.path.exists(eventprovider_directory): os.makedirs(eventprovider_directory) if not os.path.exists(eventprovider_directory + lttng_directory): os.makedirs(eventprovider_directory + lttng_directory) if not os.path.exists(eventprovider_directory + tracepointprovider_directory): os.makedirs(eventprovider_directory + tracepointprovider_directory) #Top level Cmake with open_for_update(eventprovider_directory + "CMakeLists.txt") as topCmake: topCmake.write(stdprolog_cmake + "\n") topCmake.write("""cmake_minimum_required(VERSION 2.8.12.2) project(eventprovider) set(CMAKE_INCLUDE_CURRENT_DIR ON) add_definitions(-DPAL_STDCPP_COMPAT=1) include_directories(${COREPAL_SOURCE_DIR}/inc/rt) include_directories(lttng) add_library(eventprovider STATIC """) for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerName = providerName.replace("Windows-",'') providerName = providerName.replace("Microsoft-",'') providerName_File = providerName.replace('-','') 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) # Install the static eventprovider library install(TARGETS eventprovider DESTINATION lib) """) #TracepointProvider Cmake with open_for_update(eventprovider_directory + tracepointprovider_directory + "/CMakeLists.txt") as tracepointprovider_Cmake: tracepointprovider_Cmake.write(stdprolog_cmake + "\n") tracepointprovider_Cmake.write("""cmake_minimum_required(VERSION 2.8.12.2) project(coreclrtraceptprovider) set(CMAKE_INCLUDE_CURRENT_DIR ON) add_definitions(-DPAL_STDCPP_COMPAT=1) include_directories(${COREPAL_SOURCE_DIR}/inc/rt) include_directories(../lttng/) add_compile_options(-fPIC) add_library(coreclrtraceptprovider SHARED """) for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerName = providerName.replace("Windows-",'') providerName = providerName.replace("Microsoft-",'') providerName_File = providerName.replace('-','') providerName_File = providerName_File.lower() tracepointprovider_Cmake.write(' "../'+ lttngevntprovTpPre + providerName_File +".cpp" + '"\n') tracepointprovider_Cmake.write(""" ) target_link_libraries(coreclrtraceptprovider -llttng-ust ) # Install the static coreclrtraceptprovider library install_clr(coreclrtraceptprovider) """) with open_for_update(eventprovider_directory + lttng_directory + "/eventprovhelpers.cpp") as helper: helper.write(""" #include "palrt.h" #include "pal.h" #include "stdlib.h" #include "pal_mstypes.h" #include "pal_error.h" #include <new> #include <memory.h> #define wcslen PAL_wcslen bool ResizeBuffer(char *&buffer, size_t& size, size_t currLen, size_t newSize, bool &fixedBuffer) { newSize = (size_t)(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]; if (newBuffer == NULL) return false; memcpy(newBuffer, buffer, currLen); if (!fixedBuffer) delete[] buffer; buffer = newBuffer; size = newSize; fixedBuffer = false; return true; } bool WriteToBuffer(const BYTE *src, size_t len, char *&buffer, size_t& offset, size_t& 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; } bool WriteToBuffer(PCWSTR str, char *&buffer, size_t& offset, size_t& 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; } bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& 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; } """) # Generate Lttng specific instrumentation for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerName = providerName.replace("Windows-",'') providerName = providerName.replace("Microsoft-",'') providerName_File = providerName.replace('-','') providerName_File = providerName_File.lower() providerName = providerName.replace('-','_') 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) with open_for_update(lttngevntheader) as lttnghdr_file: lttnghdr_file.write(stdprolog + "\n") lttnghdr_file.write(""" #include "palrt.h" #include "pal.h" #undef TRACEPOINT_PROVIDER """) lttnghdr_file.write("#define TRACEPOINT_PROVIDER " + providerName + "\n") lttnghdr_file.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_file.write("\n#include <lttng/tracepoint.h>\n\n") lttnghdr_file.write(generateLttngHeader(providerName,allTemplates,eventNodes) + "\n") with open_for_update(lttngevntprov) as lttngimpl_file: lttngimpl_file.write(stdprolog + "\n") lttngimpl_file.write(""" #define TRACEPOINT_DEFINE #define TRACEPOINT_PROBE_DYNAMIC_LINKAGE #include "stdlib.h" #include "pal_mstypes.h" #include "pal_error.h" #include "pal.h" #define PAL_free free #define PAL_realloc realloc #include "pal/stackstring.hpp" """) lttngimpl_file.write("#include \"" + lttngevntheadershortname + "\"\n\n") lttngimpl_file.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); template <typename T> bool WriteToBuffer(const T &value, char *&buffer, size_t& offset, size_t& 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; } """) lttngimpl_file.write(generateLttngTpProvider(providerName,eventNodes,allTemplates) + "\n") with open_for_update(lttngevntprovTp) as tpimpl_file: tpimpl_file.write(stdprolog + "\n") tpimpl_file.write("\n#define TRACEPOINT_CREATE_PROBES\n") tpimpl_file.write("#include \"./"+lttngevntheadershortname + "\"\n")
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 generateEventSources(manifestFullPath, intermediatesDirFullPath): # Open the manifest for reading. manifest = DOM.parse(manifestFullPath) # Load the string table. stringTable = loadStringTable(manifest) # Iterate over each provider that we want to generate an EventSource for. for providerName, outputFileName in manifestsToGenerate.items(): for node in manifest.getElementsByTagName("provider"): if node.getAttribute("name") == providerName: providerNode = node break if providerNode is None: raise ValueError("Unable to find provider node.", providerName) # Generate a full path to the output file and open the file for open_for_update. outputFilePath = os.path.join(intermediatesDirFullPath, outputFileName) with open_for_update(outputFilePath) as outputFile: # Write the license header. writeOutput(outputFile, generatedCodeFileHeader) # Write the class header. header = """ using System; namespace System.Diagnostics.Tracing { """ writeOutput(outputFile, header) increaseTabLevel() className = providerNameToClassNameMap[providerName] writeOutput( outputFile, "internal sealed partial class " + className + " : EventSource\n") writeOutput(outputFile, "{\n") increaseTabLevel() # Create a static property for the EventSource name so that we don't have to initialize the EventSource to get its name. writeOutput( outputFile, "internal const string EventSourceName = \"" + providerName + "\";\n") # Write the static Log property. writeOutput( outputFile, "internal static " + className + " Log = new " + className + "();\n\n") # Write the keywords class. generateKeywordsClass(providerNode, outputFile) #### Disable enums until they are needed #### # Generate the enum type map. # This determines what the backing type for each enum should be. # enumTypeMap = generateEnumTypeMap(providerNode) # Generate enums for value maps. # generateValueMapEnums(providerNode, outputFile, stringTable, enumTypeMap) # Generate enums for bit maps. # generateBitMapEnums(providerNode, outputFile, stringTable, enumTypeMap) #### Disable enums until they are needed #### # Generate events. generateEvents(providerNode, outputFile, stringTable) # Write the class footer. decreaseTabLevel() writeOutput(outputFile, "}\n") decreaseTabLevel() writeOutput(outputFile, "}")
def generateSanityTest(sClrEtwAllMan, testDir): if not testDir: return print('Generating Event Logging Tests') if not os.path.exists(testDir): os.makedirs(testDir) cmake_file = testDir + "/CMakeLists.txt" test_cpp = "clralltestevents.cpp" testinfo = testDir + "/testinfo.dat" #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} ) 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. # 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(""" /*===================================================================== ** ** Source: clralltestevents.cpp ** ** Purpose: Ensure Correctness of Eventing code ** ** **===================================================================*/ #if FEATURE_PAL #include <palsuite.h> #endif //FEATURE_PAL #include <clrxplatevents.h> typedef struct _Struct1 { ULONG Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[8]; } Struct1; Struct1 var21[2] = { { 245, 13, 14, "deadbea" }, { 542, 0, 14, "deadflu" } }; Struct1* var11 = var21; Struct1* win_Struct = var21; GUID win_GUID ={ 245, 13, 14, "deadbea" }; double win_Double =34.04; ULONG win_ULong = 34; BOOL win_Boolean = FALSE; unsigned __int64 win_UInt64 = 114; unsigned int win_UInt32 = 4; unsigned short win_UInt16 = 12; unsigned char win_UInt8 = 9; 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; } #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) /* Shutdown the PAL. */ PAL_Terminate(); #endif return PASS; } """) Testinfo.close()
def generateEventPipeImplFiles(etwmanifest, eventpipe_directory, extern, target_cpp, runtimeFlavor, inclusionList, exclusionList, dryRun): 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") for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerPrettyName = providerName.replace("Windows-", '') providerPrettyName = providerPrettyName.replace("Microsoft-", '') providerName_File = providerPrettyName.replace('-', '') if target_cpp: providerName_File = providerName_File + ".cpp" else: providerName_File = providerName_File + ".c" providerName_File = providerName_File.lower() eventpipefile = os.path.join(eventpipe_directory, providerName_File) providerPrettyName = providerPrettyName.replace('-', '_') if dryRun: print(eventpipefile) else: with open_for_update(eventpipefile) as eventpipeImpl: eventpipeImpl.write(stdprolog_cpp) header = "" if runtimeFlavor.coreclr: header = getCoreCLREventPipeImplFilePrefix() elif runtimeFlavor.mono: header = getMonoEventPipeImplFilePrefix() eventpipeImpl.write(header + "\n") eventpipeImpl.write( "const %s* %sName = W(\"%s\");\n" % (getEventPipeDataTypeMapping(runtimeFlavor)["WCHAR"], providerPrettyName, providerName)) eventpipeImpl.write( "EventPipeProvider *EventPipeProvider" + providerPrettyName + (" = nullptr;\n" if target_cpp else " = NULL;\n")) templateNodes = providerNode.getElementsByTagName('template') allTemplates = parseTemplateNodes(templateNodes) eventNodes = providerNode.getElementsByTagName('event') eventpipeImpl.write( generateClrEventPipeWriteEventsImpl( providerName, eventNodes, allTemplates, extern, target_cpp, runtimeFlavor, inclusionList, exclusionList) + "\n") if runtimeFlavor.coreclr: eventpipeImpl.write(getCoreCLREventPipeImplFileSuffix()) elif runtimeFlavor.mono: eventpipeImpl.write(getMonoEventPipeImplFileSuffix())
def generatePlatformIndependentFiles(sClrEtwAllMan, incDir, etmDummyFile, extern, write_xplatheader): generateEtmDummyHeader(sClrEtwAllMan, etmDummyFile) tree = DOM.parse(sClrEtwAllMan) if not incDir: return if not os.path.exists(incDir): os.makedirs(incDir) eventpipe_trace_context_typedef = """ #if !defined(EVENTPIPE_TRACE_CONTEXT_DEF) #define EVENTPIPE_TRACE_CONTEXT_DEF typedef struct _EVENTPIPE_TRACE_CONTEXT { WCHAR const * Name; UCHAR Level; bool IsEnabled; ULONGLONG EnabledKeywordsBitmask; } EVENTPIPE_TRACE_CONTEXT, *PEVENTPIPE_TRACE_CONTEXT; #endif // EVENTPIPE_TRACE_CONTEXT_DEF """ dotnet_trace_context_typedef_windows = """ #if !defined(DOTNET_TRACE_CONTEXT_DEF) #define DOTNET_TRACE_CONTEXT_DEF typedef struct _DOTNET_TRACE_CONTEXT { MCGEN_TRACE_CONTEXT EtwProvider; EVENTPIPE_TRACE_CONTEXT EventPipeProvider; } DOTNET_TRACE_CONTEXT, *PDOTNET_TRACE_CONTEXT; #endif // DOTNET_TRACE_CONTEXT_DEF """ dotnet_trace_context_typedef_unix = """ #if !defined(DOTNET_TRACE_CONTEXT_DEF) #define DOTNET_TRACE_CONTEXT_DEF typedef struct _DOTNET_TRACE_CONTEXT { EVENTPIPE_TRACE_CONTEXT EventPipeProvider; } DOTNET_TRACE_CONTEXT, *PDOTNET_TRACE_CONTEXT; #endif // DOTNET_TRACE_CONTEXT_DEF """ trace_context_instdef_windows = """ EXTERN_C __declspec(selectany) DOTNET_TRACE_CONTEXT MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context = { MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_EVENTPIPE_Context }; EXTERN_C __declspec(selectany) DOTNET_TRACE_CONTEXT MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_DOTNET_Context = { MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_EVENTPIPE_Context }; EXTERN_C __declspec(selectany) DOTNET_TRACE_CONTEXT MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context = { MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context, MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_EVENTPIPE_Context }; EXTERN_C __declspec(selectany) DOTNET_TRACE_CONTEXT MICROSOFT_WINDOWS_DOTNETRUNTIME_STRESS_PROVIDER_DOTNET_Context = { MICROSOFT_WINDOWS_DOTNETRUNTIME_STRESS_PROVIDER_Context, MICROSOFT_WINDOWS_DOTNETRUNTIME_STRESS_PROVIDER_EVENTPIPE_Context }; """ trace_context_instdef_unix = """ EXTERN_C __declspec(selectany) DOTNET_TRACE_CONTEXT MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context = { MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_EVENTPIPE_Context }; EXTERN_C __declspec(selectany) DOTNET_TRACE_CONTEXT MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_DOTNET_Context = { MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_EVENTPIPE_Context }; EXTERN_C __declspec(selectany) DOTNET_TRACE_CONTEXT MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_DOTNET_Context = { MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_EVENTPIPE_Context }; EXTERN_C __declspec(selectany) DOTNET_TRACE_CONTEXT MICROSOFT_WINDOWS_DOTNETRUNTIME_STRESS_PROVIDER_DOTNET_Context = { MICROSOFT_WINDOWS_DOTNETRUNTIME_STRESS_PROVIDER_EVENTPIPE_Context }; """ # Write the main header for FireETW* functions clrallevents = os.path.join(incDir, "clretwallmain.h") is_windows = os.name == 'nt' with open_for_update(clrallevents) as Clrallevents: Clrallevents.write(stdprolog) Clrallevents.write(""" #include "clrxplatevents.h" #include "clreventpipewriteevents.h" """) Clrallevents.write( eventpipe_trace_context_typedef) # define EVENTPIPE_TRACE_CONTEXT # define DOTNET_TRACE_CONTEXT depending on the platform if is_windows: Clrallevents.write(dotnet_trace_context_typedef_windows) else: Clrallevents.write(dotnet_trace_context_typedef_unix) 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") providerName = providerNode.getAttribute('name') providerSymbol = providerNode.getAttribute('symbol') eventpipeProviderCtxName = providerSymbol + "_EVENTPIPE_Context" Clrallevents.write( 'EXTERN_C __declspec(selectany) EVENTPIPE_TRACE_CONTEXT ' + eventpipeProviderCtxName + ' = { W("' + providerName + '"), 0, false, 0 };\n') # define and initialize runtime providers' DOTNET_TRACE_CONTEXT depending on the platform if is_windows: Clrallevents.write(trace_context_instdef_windows) else: Clrallevents.write(trace_context_instdef_unix) if write_xplatheader: clrproviders = os.path.join(incDir, "clrproviders.h") with open_for_update(clrproviders) as Clrproviders: Clrproviders.write(""" typedef struct _EVENT_DESCRIPTOR { int const Level; ULONGLONG const Keyword; } EVENT_DESCRIPTOR; """) allProviders = [] for providerNode in tree.getElementsByTagName('provider'): keywords = [] keywordsToMask = {} providerName = str(providerNode.getAttribute('name')) providerSymbol = str(providerNode.getAttribute('symbol')) nbKeywords = 0 Clrproviders.write("// Keywords\n") for keywordNode in providerNode.getElementsByTagName( 'keyword'): keywordName = keywordNode.getAttribute('name') keywordMask = keywordNode.getAttribute('mask') keywordSymbol = keywordNode.getAttribute('symbol') Clrproviders.write("#define " + keywordSymbol + " " + keywordMask + "\n") keywords.append("{ \"" + keywordName + "\", " + keywordMask + " }") keywordsToMask[keywordName] = int(keywordMask, 16) nbKeywords += 1 for eventNode in providerNode.getElementsByTagName('event'): levelName = eventNode.getAttribute('level') symbolName = eventNode.getAttribute('symbol') keywords = eventNode.getAttribute('keywords') level = convertToLevelId(levelName) Clrproviders.write( "EXTERN_C __declspec(selectany) EVENT_DESCRIPTOR const " + symbolName + " = { " + str(level) + ", " + hex(getKeywordsMaskCombined(keywords, keywordsToMask)) + " };\n") allProviders.append("&" + providerSymbol + "_Context") clreventpipewriteevents = os.path.join(incDir, "clreventpipewriteevents.h") with open_for_update(clreventpipewriteevents) as Clreventpipewriteevents: Clreventpipewriteevents.write(stdprolog + "\n") for providerNode in tree.getElementsByTagName('provider'): templateNodes = providerNode.getElementsByTagName('template') allTemplates = parseTemplateNodes(templateNodes) eventNodes = providerNode.getElementsByTagName('event') #eventpipe: create clreventpipewriteevents.h Clreventpipewriteevents.write( generateClrEventPipeWriteEvents(eventNodes, allTemplates, extern) + "\n") # Write secondary headers for FireEtXplat* and EventPipe* functions if write_xplatheader: clrxplatevents = os.path.join(incDir, "clrxplatevents.h") with open_for_update(clrxplatevents) as Clrxplatevents: Clrxplatevents.write(stdprolog + "\n") for providerNode in tree.getElementsByTagName('provider'): templateNodes = providerNode.getElementsByTagName('template') allTemplates = parseTemplateNodes(templateNodes) eventNodes = providerNode.getElementsByTagName('event') #pal: create clrallevents.h Clrxplatevents.write( generateClrXplatEvents(eventNodes, allTemplates, extern) + "\n")
def generateSanityTest(sClrEtwAllMan,testDir): if not os.path.exists(testDir): os.makedirs(testDir) test_cpp = testDir + "/clralltestevents.cpp" testinfo = testDir + "/testinfo.dat" with open_for_update(testinfo) as Testinfo: 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(test_cpp) as Test_cpp: Test_cpp.write(stdprolog) Test_cpp.write(""" /*===================================================================== ** ** Source: clralltestevents.cpp ** ** Purpose: Ensure Correctness of Eventing code ** ** **===================================================================*/ #if FEATURE_PAL #include <palsuite.h> #endif //FEATURE_PAL #include <clrxplatevents.h> typedef struct _Struct1 { ULONG Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[8]; } Struct1; Struct1 var21[2] = { { 245, 13, 14, "deadbea" }, { 542, 0, 14, "deadflu" } }; Struct1* var11 = var21; Struct1* win_Struct = var21; GUID win_GUID ={ 245, 13, 14, "deadbea" }; double win_Double =34.04; ULONG win_ULong = 34; BOOL win_Boolean = FALSE; unsigned __int64 win_UInt64 = 114; unsigned int win_UInt32 = 4; unsigned short win_UInt16 = 12; unsigned char win_UInt8 = 9; 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; } #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) /* Shutdown the PAL. */ PAL_Terminate(); #endif return PASS; } """) Testinfo.close()
def generateEventPipeImplFiles( etwmanifest, eventpipe_directory, extern, exclusionList, dryRun): 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") for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerPrettyName = providerName.replace("Windows-", '') providerPrettyName = providerPrettyName.replace("Microsoft-", '') providerName_File = providerPrettyName.replace('-', '') providerName_File = providerName_File.lower() providerPrettyName = providerPrettyName.replace('-', '_') eventpipefile = os.path.join(eventpipe_directory, providerName_File + ".cpp") if dryRun: print(eventpipefile) else: 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" #if defined(TARGET_UNIX) #define wcslen PAL_wcslen #endif 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); template <typename T> bool WriteToBuffer(const T &value, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) {{ if (sizeof(T) + offset > size) {{ if (!ResizeBuffer(buffer, size, offset, size + sizeof(T), fixedBuffer)) return false; }} memcpy(buffer + offset, (char *)&value, sizeof(T)); offset += sizeof(T); return true; }} """.format(root=src_dirname.replace('\\', '/')) eventpipeImpl.write(header) eventpipeImpl.write( "const WCHAR* %sName = W(\"%s\");\n" % ( providerPrettyName, providerName ) ) 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, exclusionList) + "\n")
def generateEventSources(manifestFullPath, intermediatesDirFullPath): # Open the manifest for reading. manifest = DOM.parse(manifestFullPath) # Load the string table. stringTable = loadStringTable(manifest) # Iterate over each provider that we want to generate an EventSource for. for providerName, outputFileName in manifestsToGenerate.items(): for node in manifest.getElementsByTagName("provider"): if node.getAttribute("name") == providerName: providerNode = node break if providerNode is None: raise ValueError("Unable to find provider node.", providerName) # Generate a full path to the output file and open the file for open_for_update. outputFilePath = os.path.join(intermediatesDirFullPath, outputFileName) with open_for_update(outputFilePath) as outputFile: # Write the license header. writeOutput(outputFile, generatedCodeFileHeader) # Write the class header. header = """ using System; namespace System.Diagnostics.Tracing { """ writeOutput(outputFile, header) increaseTabLevel() className = providerNameToClassNameMap[providerName] writeOutput(outputFile, "internal sealed partial class " + className + " : EventSource\n") writeOutput(outputFile, "{\n") increaseTabLevel() # Create a static property for the EventSource name so that we don't have to initialize the EventSource to get its name. writeOutput(outputFile, "internal const string EventSourceName = \"" + providerName + "\";\n") # Write the static Log property. writeOutput(outputFile, "internal static " + className + " Log = new " + className + "();\n\n") # Write the keywords class. generateKeywordsClass(providerNode, outputFile) #### Disable enums until they are needed #### # Generate the enum type map. # This determines what the backing type for each enum should be. # enumTypeMap = generateEnumTypeMap(providerNode) # Generate enums for value maps. # generateValueMapEnums(providerNode, outputFile, stringTable, enumTypeMap) # Generate enums for bit maps. # generateBitMapEnums(providerNode, outputFile, stringTable, enumTypeMap) #### Disable enums until they are needed #### # Generate events. generateEvents(providerNode, outputFile, stringTable) # Write the class footer. decreaseTabLevel() writeOutput(outputFile, "}\n") decreaseTabLevel() writeOutput(outputFile, "}")
def generateSanityTest(sClrEtwAllMan,testDir): if not testDir: return print('Generating Event Logging Tests') if not os.path.exists(testDir): os.makedirs(testDir) cmake_file = testDir + "/CMakeLists.txt" test_cpp = "clralltestevents.cpp" testinfo = testDir + "/testinfo.dat" #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} ) 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. # 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(""" /*===================================================================== ** ** Source: clralltestevents.cpp ** ** Purpose: Ensure Correctness of Eventing code ** ** **===================================================================*/ #if FEATURE_PAL #include <palsuite.h> #endif //FEATURE_PAL #include <clrxplatevents.h> typedef struct _Struct1 { ULONG Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[8]; } Struct1; Struct1 var21[2] = { { 245, 13, 14, "deadbea" }, { 542, 0, 14, "deadflu" } }; Struct1* var11 = var21; Struct1* win_Struct = var21; GUID win_GUID ={ 245, 13, 14, "deadbea" }; double win_Double =34.04; ULONG win_ULong = 34; BOOL win_Boolean = FALSE; unsigned __int64 win_UInt64 = 114; unsigned int win_UInt32 = 4; unsigned short win_UInt16 = 12; unsigned char win_UInt8 = 9; 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; } #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) /* Shutdown the PAL. */ PAL_Terminate(); #endif return PASS; } """) Testinfo.close()
def generateEventPipeHelperFile(etwmanifest, eventpipe_directory, extern, dryRun): eventpipehelpersPath = os.path.join(eventpipe_directory, "eventpipehelpers.cpp") if dryRun: print(eventpipehelpersPath) else: with open_for_update(eventpipehelpersPath) as helper: helper.write(stdprolog_cpp) helper.write(""" #include "common.h" #include <stdlib.h> #include <string.h> #ifndef TARGET_UNIX #include <windef.h> #include <crtdbg.h> #else #include "pal.h" #endif //TARGET_UNIX bool ResizeBuffer(char *&buffer, size_t& size, size_t currLen, size_t newSize, bool &fixedBuffer) { newSize = (size_t)(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; memcpy(newBuffer, buffer, currLen); if (!fixedBuffer) delete[] buffer; buffer = newBuffer; size = newSize; fixedBuffer = false; return true; } bool WriteToBuffer(const BYTE *src, size_t len, char *&buffer, size_t& offset, size_t& 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; } bool WriteToBuffer(PCWSTR str, char *&buffer, size_t& offset, size_t& 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; } bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& 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; } """) tree = DOM.parse(etwmanifest) for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerPrettyName = providerName.replace("Windows-", '') providerPrettyName = providerPrettyName.replace("Microsoft-", '') providerPrettyName = providerPrettyName.replace('-', '_') if extern: helper.write( 'extern "C" ' ) helper.write( "void Init" + providerPrettyName + "();\n\n") if extern: helper.write( 'extern "C" ' ) helper.write("void InitProvidersAndEvents()\n{\n") for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerPrettyName = providerName.replace("Windows-", '') providerPrettyName = providerPrettyName.replace("Microsoft-", '') providerPrettyName = providerPrettyName.replace('-', '_') helper.write(" Init" + providerPrettyName + "();\n") helper.write("}") helper.close()
def generateEventPipeHelperFile(etwmanifest, eventpipe_directory, extern): with open_for_update(os.path.join(eventpipe_directory, "eventpipehelpers.cpp")) as helper: helper.write(stdprolog_cpp) 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) { newSize = (size_t)(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; memcpy(newBuffer, buffer, currLen); if (!fixedBuffer) delete[] buffer; buffer = newBuffer; size = newSize; fixedBuffer = false; return true; } bool WriteToBuffer(const BYTE *src, size_t len, char *&buffer, size_t& offset, size_t& 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; } bool WriteToBuffer(PCWSTR str, char *&buffer, size_t& offset, size_t& 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; } bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& 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; } """) tree = DOM.parse(etwmanifest) for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerPrettyName = providerName.replace("Windows-", '') providerPrettyName = providerPrettyName.replace("Microsoft-", '') providerPrettyName = providerPrettyName.replace('-', '_') if extern: helper.write( 'extern "C" ' ) helper.write( "void Init" + providerPrettyName + "();\n\n") if extern: helper.write( 'extern "C" ' ) helper.write("void InitProvidersAndEvents()\n{\n") for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerPrettyName = providerName.replace("Windows-", '') providerPrettyName = providerPrettyName.replace("Microsoft-", '') providerPrettyName = providerPrettyName.replace('-', '_') helper.write(" Init" + providerPrettyName + "();\n") helper.write("}") helper.close()
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 generateEventPipeImplFiles( etwmanifest, eventpipe_directory, extern): 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") for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerPrettyName = providerName.replace("Windows-", '') providerPrettyName = providerPrettyName.replace("Microsoft-", '') 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" #if defined(FEATURE_PAL) #define wcslen PAL_wcslen #endif 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); template <typename T> bool WriteToBuffer(const T &value, char *&buffer, size_t& offset, size_t& 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; }} """.format(root=src_dirname.replace('\\', '/')) eventpipeImpl.write(header) eventpipeImpl.write( "const WCHAR* %sName = W(\"%s\");\n" % ( providerPrettyName, providerName ) ) 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")