summaryrefslogtreecommitdiff
path: root/src/scripts
diff options
context:
space:
mode:
authorBrian Robbins <brianrob@microsoft.com>2017-05-06 12:36:08 -0700
committerVance Morrison <vancem@microsoft.com>2017-05-06 12:36:08 -0700
commit72ac46450bec8ea88ed023d9c1faf5a04556c834 (patch)
tree59085824f4268257d041ed9870f038216cd8ed45 /src/scripts
parent3ababc21ab334a2e37c6ba4115c946ea26a6f2fb (diff)
downloadcoreclr-72ac46450bec8ea88ed023d9c1faf5a04556c834.tar.gz
coreclr-72ac46450bec8ea88ed023d9c1faf5a04556c834.tar.bz2
coreclr-72ac46450bec8ea88ed023d9c1faf5a04556c834.zip
Log Events to EventPipe on Linux (#11433)
* Implement the EventPipe object model for providers and events. * Plumb Runtime Events into EventPipe (#11145) Plumb runtime ETW events into the EventPipe. * Fix bug where all events except for SampleProfiler events were never enabled. * Plumb EventPipeEventInstance through the EventPipe. * Implement EventPipeFile and FastSerializer. * Write event contents to the EventPipeFile. * Only build EventPipe on Linux. * Conditionally add a sentinel value marking event end. * Send SampleProfiler events to the EventPipeFile. * Fix provider ID printing to JSON file. * Write the start date/time, timestamp, and clock frequency into the trace file. * Support unloading of EventPipeProviders. * Handle failure cases when we can't walk the stack or are shutting down. * Fix a bug where we pass a null src pointer to memcpy.
Diffstat (limited to 'src/scripts')
-rw-r--r--src/scripts/genEventPipe.py500
-rw-r--r--src/scripts/genXplatEventing.py89
-rw-r--r--src/scripts/genXplatLttng.py6
3 files changed, 582 insertions, 13 deletions
diff --git a/src/scripts/genEventPipe.py b/src/scripts/genEventPipe.py
new file mode 100644
index 0000000000..3a818ce1e0
--- /dev/null
+++ b/src/scripts/genEventPipe.py
@@ -0,0 +1,500 @@
+from __future__ import print_function
+from genXplatEventing import *
+from genXplatLttng import *
+import os
+import xml.dom.minidom as DOM
+
+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/genEventPipe.py
+
+******************************************************************/
+"""
+
+stdprolog_cmake = """#
+#
+#******************************************************************
+
+#DO NOT MODIFY. AUTOGENERATED FILE.
+#This file is generated using the logic from <root>/src/scripts/genEventPipe.py
+
+#******************************************************************
+"""
+
+
+def generateClrEventPipeWriteEventsImpl(
+ providerName, eventNodes, allTemplates, exclusionListFile):
+ providerPrettyName = providerName.replace("Windows-", '')
+ providerPrettyName = providerPrettyName.replace("Microsoft-", '')
+ providerPrettyName = providerPrettyName.replace('-', '_')
+ WriteEventImpl = []
+
+ # EventPipeEvent declaration
+ for eventNode in eventNodes:
+ eventName = eventNode.getAttribute('symbol')
+ WriteEventImpl.append(
+ "EventPipeEvent *EventPipeEvent" +
+ eventName +
+ " = nullptr;\n")
+
+ for eventNode in eventNodes:
+ eventName = eventNode.getAttribute('symbol')
+ templateName = eventNode.getAttribute('template')
+
+ # generate EventPipeEventEnabled function
+ eventEnabledImpl = """bool EventPipeEventEnabled%s()
+{
+ return EventPipeEvent%s->IsEnabled();
+}
+
+""" % (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
+
+ 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)
+
+ fnptype.append(checking)
+
+ WriteEventImpl.extend(fnptype)
+
+ if template:
+ body = generateWriteEventBody(template, providerName, eventName)
+ WriteEventImpl.append(body)
+ else:
+ WriteEventImpl.append(
+ " EventPipe::WriteEvent(*EventPipeEvent" +
+ eventName +
+ ", nullptr, 0);\n")
+
+ WriteEventImpl.append("\n return ERROR_SUCCESS;\n}\n\n")
+
+ # EventPipeProvider and EventPipeEvent initialization
+ WriteEventImpl.append(
+ "extern \"C\" void Init" +
+ providerPrettyName +
+ "()\n{\n")
+ WriteEventImpl.append(
+ " EventPipeProvider" +
+ providerPrettyName +
+ " = new EventPipeProvider(" +
+ providerPrettyName +
+ "GUID);\n")
+ for eventNode in eventNodes:
+ eventName = eventNode.getAttribute('symbol')
+ templateName = eventNode.getAttribute('template')
+ eventKeywords = eventNode.getAttribute('keywords')
+ eventKeywordsMask = generateEventKeywords(eventKeywords)
+ eventValue = eventNode.getAttribute('value')
+ eventVersion = eventNode.getAttribute('version')
+ eventLevel = eventNode.getAttribute('level')
+ eventLevel = eventLevel.replace("win:", "EventPipeEventLevel::")
+ exclusionInfo = parseExclusionList(exclusionListFile)
+ taskName = eventNode.getAttribute('task')
+ noStack = getStackWalkBit(
+ providerName,
+ taskName,
+ eventName,
+ exclusionInfo.nostack)
+
+ initEvent = """ EventPipeEvent%s = EventPipeProvider%s->AddEvent(%s,%s,%s,%s,%d);
+""" % (eventName, providerPrettyName, eventKeywordsMask, eventValue, eventVersion, eventLevel, int(noStack))
+
+ WriteEventImpl.append(initEvent)
+ WriteEventImpl.append("}")
+
+ return ''.join(WriteEventImpl)
+
+
+def generateWriteEventBody(template, providerName, eventName):
+ header = """
+ char stackBuffer[%s];
+ char *buffer = stackBuffer;
+ unsigned int offset = 0;
+ unsigned int size = %s;
+ bool fixedBuffer = true;
+
+ bool success = true;
+""" % (template.estimated_size, template.estimated_size)
+
+ fnSig = template.signature
+ pack_list = []
+ for paramName in fnSig.paramlist:
+ parameter = fnSig.getParam(paramName)
+
+ if paramName in template.structs:
+ size = "(int)%s_ElementSize * (int)%s" % (
+ paramName, parameter.prop)
+ if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]:
+ size = "(int)(%s)" % specialCaseSizes[template.name][paramName]
+ pack_list.append(
+ " success &= WriteToBuffer((const BYTE *)%s, %s, buffer, offset, size, fixedBuffer);" %
+ (paramName, size))
+ elif paramName in template.arrays:
+ size = "sizeof(%s) * (int)%s" % (
+ lttngDataTypeMapping[parameter.winType],
+ parameter.prop)
+ if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]:
+ size = "(int)(%s)" % specialCaseSizes[template.name][paramName]
+ pack_list.append(
+ " success &= WriteToBuffer((const BYTE *)%s, %s, buffer, offset, size, fixedBuffer);" %
+ (paramName, size))
+ elif parameter.winType == "win:GUID":
+ pack_list.append(
+ " success &= WriteToBuffer(*%s, buffer, offset, size, fixedBuffer);" %
+ (parameter.name,))
+ else:
+ pack_list.append(
+ " success &= WriteToBuffer(%s, buffer, offset, size, fixedBuffer);" %
+ (parameter.name,))
+
+ code = "\n".join(pack_list) + "\n\n"
+
+ checking = """ if (!success)
+ {
+ if (!fixedBuffer)
+ delete[] buffer;
+ return ERROR_WRITE_FAULT;
+ }\n\n"""
+
+ body = " EventPipe::WriteEvent(*EventPipeEvent" + \
+ eventName + ", (BYTE *)buffer, size);\n"
+
+ footer = """
+ if (!fixedBuffer)
+ delete[] buffer;
+"""
+
+ return header + code + checking + body + footer
+
+providerGUIDMap = {}
+providerGUIDMap[
+ "{e13c0d23-ccbc-4e12-931b-d9cc2eee27e4}"] = "{0xe13c0d23,0xccbc,0x4e12,{0x93,0x1b,0xd9,0xcc,0x2e,0xee,0x27,0xe4}}"
+providerGUIDMap[
+ "{A669021C-C450-4609-A035-5AF59AF4DF18}"] = "{0xA669021C,0xC450,0x4609,{0xA0,0x35,0x5A,0xF5,0x9A,0xF4,0xDF,0x18}}"
+providerGUIDMap[
+ "{CC2BCBBA-16B6-4cf3-8990-D74C2E8AF500}"] = "{0xCC2BCBBA,0x16B6,0x4cf3,{0x89,0x90,0xD7,0x4C,0x2E,0x8A,0xF5,0x00}}"
+providerGUIDMap[
+ "{763FD754-7086-4dfe-95EB-C01A46FAF4CA}"] = "{0x763FD754,0x7086,0x4dfe,{0x95,0xEB,0xC0,0x1A,0x46,0xFA,0xF4,0xCA}}"
+
+
+def generateGUID(tmpGUID):
+ return providerGUIDMap[tmpGUID]
+
+keywordMap = {}
+
+
+def generateEventKeywords(eventKeywords):
+ mask = 0
+ # split keywords if there are multiple
+ allKeywords = eventKeywords.split()
+
+ for singleKeyword in allKeywords:
+ mask = mask | keywordMap[singleKeyword]
+
+ return mask
+
+
+def generateEventPipeCmakeFile(etwmanifest, eventpipe_directory):
+ tree = DOM.parse(etwmanifest)
+
+ with open(eventpipe_directory + "CMakeLists.txt", 'w') as topCmake:
+ topCmake.write(stdprolog_cmake + "\n")
+ topCmake.write("""cmake_minimum_required(VERSION 2.8.12.2)
+
+ project(eventpipe)
+
+ 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')
+ providerName = providerName.replace("Windows-", '')
+ providerName = providerName.replace("Microsoft-", '')
+
+ providerName_File = providerName.replace('-', '')
+ providerName_File = providerName_File.lower()
+
+ topCmake.write(' "%s.cpp"\n' % (providerName_File))
+ topCmake.write(' "eventpipehelpers.cpp"\n')
+ topCmake.write(""" )
+
+ # Install the static eventpipe library
+ install(TARGETS eventpipe DESTINATION lib)
+ """)
+
+ topCmake.close()
+
+
+def generateEventPipeHelperFile(etwmanifest, eventpipe_directory):
+ with open(eventpipe_directory + "eventpipehelpers.cpp", 'w') as helper:
+ helper.write(stdprolog)
+ helper.write("""
+#include "stdlib.h"
+
+bool ResizeBuffer(char *&buffer, unsigned int& size, unsigned int currLen, unsigned int newSize, bool &fixedBuffer)
+{
+ newSize *= 1.5;
+ _ASSERTE(newSize > size); // check for overflow
+
+ if (newSize < 32)
+ newSize = 32;
+
+ char *newBuffer = new char[newSize];
+
+ memcpy(newBuffer, buffer, currLen);
+
+ if (!fixedBuffer)
+ delete[] buffer;
+
+ buffer = newBuffer;
+ size = newSize;
+ fixedBuffer = false;
+
+ return true;
+}
+
+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)
+ {
+ 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, unsigned int& offset, unsigned int& size, bool &fixedBuffer)
+{
+ if(!str) return true;
+ unsigned 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, unsigned int& offset, unsigned int& size, bool &fixedBuffer)
+{
+ if(!str) return true;
+ unsigned 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;
+}
+
+""")
+
+ 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('-', '_')
+ helper.write(
+ "extern \"C\" void Init" +
+ providerPrettyName +
+ "();\n\n")
+
+ helper.write("extern \"C\" 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 generateEventPipeImplFiles(
+ etwmanifest, eventpipe_directory, exclusionListFile):
+ tree = DOM.parse(etwmanifest)
+ coreclrRoot = os.getcwd()
+ for providerNode in tree.getElementsByTagName('provider'):
+ providerGUID = providerNode.getAttribute('guid')
+ providerGUID = generateGUID(providerGUID)
+ 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 = eventpipe_directory + providerName_File + ".cpp"
+ eventpipeImpl = open(eventpipefile, 'w')
+ eventpipeImpl.write(stdprolog)
+
+ 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, 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, unsigned int& offset, unsigned 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;
+}
+
+""" % (coreclrRoot, coreclrRoot, coreclrRoot, coreclrRoot)
+
+ eventpipeImpl.write(header)
+ eventpipeImpl.write(
+ "GUID const " +
+ providerPrettyName +
+ "GUID = " +
+ providerGUID +
+ ";\n")
+ eventpipeImpl.write(
+ "EventPipeProvider *EventPipeProvider" +
+ providerPrettyName +
+ " = nullptr;\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, 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, eventpipe_directory)
+
+ # generate helper file
+ generateEventPipeHelperFile(etwmanifest, eventpipe_directory)
+
+ # generate all keywords
+ for keywordNode in tree.getElementsByTagName('keyword'):
+ keywordName = keywordNode.getAttribute('name')
+ keywordMask = keywordNode.getAttribute('mask')
+ keywordMap[keywordName] = int(keywordMask, 0)
+
+ # generate .cpp file for each provider
+ generateEventPipeImplFiles(
+ etwmanifest,
+ eventpipe_directory,
+ exclusionListFile)
+
+import argparse
+import sys
+
+
+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('--intermediate', type=str, required=True,
+ help='full path to eventprovider intermediate directory')
+ 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 const.UnknownArguments
+
+ sClrEtwAllMan = args.man
+ intermediate = args.intermediate
+ exclusionListFile = args.exc
+
+ generateEventPipeFiles(sClrEtwAllMan, intermediate, exclusionListFile)
+
+if __name__ == '__main__':
+ return_code = main(sys.argv[1:])
+ sys.exit(return_code)
diff --git a/src/scripts/genXplatEventing.py b/src/scripts/genXplatEventing.py
index 6c6498d3de..6968d293e9 100644
--- a/src/scripts/genXplatEventing.py
+++ b/src/scripts/genXplatEventing.py
@@ -39,7 +39,7 @@ stdprolog_cmake="""
#******************************************************************
"""
-lindent = " ";
+lindent = " ";
palDataTypeMapping ={
#constructed types
"win:null" :" ",
@@ -282,18 +282,17 @@ def generateClrallEvents(eventNodes,allTemplates):
#generate EventEnabled
clrallEvents.append("inline BOOL EventEnabled")
clrallEvents.append(eventName)
- clrallEvents.append("() {return XplatEventLogger::IsEventLoggingEnabled() && EventXplatEnabled")
- clrallEvents.append(eventName+"();}\n\n")
+ clrallEvents.append("() {return ")
+ clrallEvents.append("EventPipeEventEnabled" + eventName + "() || ")
+ clrallEvents.append("(XplatEventLogger::IsEventLoggingEnabled() && EventXplatEnabled")
+ clrallEvents.append(eventName+"());}\n\n")
#generate FireEtw functions
fnptype = []
fnbody = []
fnptype.append("inline ULONG FireEtw")
fnptype.append(eventName)
fnptype.append("(\n")
- fnbody.append(lindent)
- fnbody.append("if (!EventEnabled")
- fnbody.append(eventName)
- fnbody.append("()) {return ERROR_SUCCESS;}\n")
+
line = []
fnptypeline = []
@@ -339,11 +338,22 @@ def generateClrallEvents(eventNodes,allTemplates):
fnptype.extend(fnptypeline)
fnptype.append("\n)\n{\n")
fnbody.append(lindent)
- fnbody.append("return FireEtXplat")
+ fnbody.append("ULONG status = EventPipeWriteEvent" + eventName + "(" + ''.join(line) + ");\n")
+ fnbody.append(lindent)
+ fnbody.append("if(XplatEventLogger::IsEventLoggingEnabled())\n")
+ fnbody.append(lindent)
+ fnbody.append("{\n")
+ fnbody.append(lindent)
+ fnbody.append(lindent)
+ fnbody.append("status &= FireEtXplat")
fnbody.append(eventName)
fnbody.append("(")
fnbody.extend(line)
fnbody.append(");\n")
+ fnbody.append(lindent)
+ fnbody.append("}\n")
+ fnbody.append(lindent)
+ fnbody.append("return status;\n")
fnbody.append("}\n\n")
clrallEvents.extend(fnptype)
@@ -400,6 +410,57 @@ def generateClrXplatEvents(eventNodes, allTemplates):
return ''.join(clrallEvents)
+def generateClrEventPipeWriteEvents(eventNodes, allTemplates):
+ clrallEvents = []
+ for eventNode in eventNodes:
+ eventName = eventNode.getAttribute('symbol')
+ templateName = eventNode.getAttribute('template')
+
+ #generate EventPipeEventEnabled and EventPipeWriteEvent functions
+ eventenabled = []
+ writeevent = []
+ fnptypeline = []
+
+ eventenabled.append("extern \"C\" bool EventPipeEventEnabled")
+ eventenabled.append(eventName)
+ eventenabled.append("();\n")
+
+ writeevent.append("extern \"C\" ULONG EventPipeWriteEvent")
+ writeevent.append(eventName)
+ writeevent.append("(\n")
+
+ if templateName:
+ template = allTemplates[templateName]
+ fnSig = template.signature
+
+ for params in fnSig.paramlist:
+ fnparam = fnSig.getParam(params)
+ wintypeName = fnparam.winType
+ typewName = palDataTypeMapping[wintypeName]
+ winCount = fnparam.count
+ countw = palDataTypeMapping[winCount]
+
+ if params in template.structs:
+ fnptypeline.append("%sint %s_ElementSize,\n" % (lindent, params))
+
+ fnptypeline.append(lindent)
+ fnptypeline.append(typewName)
+ fnptypeline.append(countw)
+ fnptypeline.append(" ")
+ fnptypeline.append(fnparam.name)
+ fnptypeline.append(",\n")
+
+ #remove trailing commas
+ if len(fnptypeline) > 0:
+ del fnptypeline[-1]
+
+ writeevent.extend(fnptypeline)
+ writeevent.append("\n);\n")
+ clrallEvents.extend(eventenabled)
+ clrallEvents.extend(writeevent)
+
+ return ''.join(clrallEvents)
+
#generates the dummy header file which is used by the VM as entry point to the logging Functions
def generateclrEtwDummy(eventNodes,allTemplates):
clretmEvents = []
@@ -670,15 +731,19 @@ def generatePlformIndependentFiles(sClrEtwAllMan,incDir,etmDummyFile):
clrallevents = incDir + "/clretwallmain.h"
clrxplatevents = incDir + "/clrxplatevents.h"
+ clreventpipewriteevents = incDir + "/clreventpipewriteevents.h"
Clrallevents = open(clrallevents,'w')
Clrxplatevents = open(clrxplatevents,'w')
+ Clreventpipewriteevents = open(clreventpipewriteevents,'w')
Clrallevents.write(stdprolog + "\n")
Clrxplatevents.write(stdprolog + "\n")
+ Clreventpipewriteevents.write(stdprolog + "\n")
- Clrallevents.write("\n#include \"clrxplatevents.h\"\n\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)
@@ -689,8 +754,12 @@ def generatePlformIndependentFiles(sClrEtwAllMan,incDir,etmDummyFile):
#pal: create clrallevents.h
Clrxplatevents.write(generateClrXplatEvents(eventNodes, allTemplates) + "\n")
+ #eventpipe: create clreventpipewriteevents.h
+ Clreventpipewriteevents.write(generateClrEventPipeWriteEvents(eventNodes, allTemplates) + "\n")
+
Clrxplatevents.close()
Clrallevents.close()
+ Clreventpipewriteevents.close()
class EventExclusions:
def __init__(self):
diff --git a/src/scripts/genXplatLttng.py b/src/scripts/genXplatLttng.py
index 6dd60b0a0b..fae0e120da 100644
--- a/src/scripts/genXplatLttng.py
+++ b/src/scripts/genXplatLttng.py
@@ -594,7 +594,7 @@ bool ResizeBuffer(char *&buffer, int& size, int currLen, int newSize, bool &fixe
bool WriteToBuffer(const BYTE *src, int len, char *&buffer, int& offset, int& size, bool &fixedBuffer)
{
if (!src) return true;
- if (offset + len)
+ if (offset + len > size)
{
if (!ResizeBuffer(buffer, size, offset, size + len, fixedBuffer))
return false;
@@ -610,7 +610,7 @@ bool WriteToBuffer(PCWSTR str, char *&buffer, int& offset, int& size, bool &fixe
if (!str) return true;
int byteCount = (PAL_wcslen(str) + 1) * sizeof(*str);
- if (offset + byteCount)
+ if (offset + byteCount > size)
{
if (!ResizeBuffer(buffer, size, offset, size + byteCount, fixedBuffer))
return false;
@@ -625,7 +625,7 @@ bool WriteToBuffer(const char *str, char *&buffer, int& offset, int& size, bool
{
if (!str) return true;
int len = strlen(str) + 1;
- if (offset + len)
+ if (offset + len > size)
{
if (!ResizeBuffer(buffer, size, offset, size + len, fixedBuffer))
return false;