summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Au <andrewau@microsoft.com>2019-03-18 15:19:45 -0700
committerAndrew Au <cshung@gmail.com>2019-03-21 17:11:06 -0400
commita7c9ca110096c27de23f045cd176c2109d0676d9 (patch)
tree45dd6a3064babadad30f4746b7ab9864f6a00055
parentceca0a77e8b48e30f9c6b67d2992c3276aba2177 (diff)
downloadcoreclr-a7c9ca110096c27de23f045cd176c2109d0676d9.tar.gz
coreclr-a7c9ca110096c27de23f045cd176c2109d0676d9.tar.bz2
coreclr-a7c9ca110096c27de23f045cd176c2109d0676d9.zip
Avoid stack walk as specified in the exclusion list
-rw-r--r--build.cmd4
-rwxr-xr-xbuild.sh2
-rw-r--r--src/scripts/genEtwProvider.py53
-rw-r--r--src/scripts/genEventPipe.py29
-rw-r--r--src/scripts/utilities.py46
-rw-r--r--src/vm/eventpipeeventsource.cpp1
-rw-r--r--src/vm/eventpipeinternal.cpp2
-rw-r--r--src/vm/eventpipeprovider.cpp13
-rw-r--r--src/vm/eventpipeprovider.h9
9 files changed, 75 insertions, 84 deletions
diff --git a/build.cmd b/build.cmd
index 3617b1b48a..1502783ab9 100644
--- a/build.cmd
+++ b/build.cmd
@@ -426,7 +426,7 @@ if %__BuildNative% EQU 1 (
"!PYTHON!" -B -Wall %__SourceDir%\scripts\genEventing.py --inc %__IntermediatesIncDir% --dummy %__IntermediatesIncDir%\etmdummy.h --man %__SourceDir%\vm\ClrEtwAll.man --nonextern --noxplatheader|| exit /b 1
echo %__MsgPrefix%Laying out dynamically generated EventPipe Implementation
- "!PYTHON!" -B -Wall %__SourceDir%\scripts\genEventPipe.py --man %__SourceDir%\vm\ClrEtwAll.man --intermediate %__IntermediatesEventingDir%\eventpipe --nonextern || exit /b 1
+ "!PYTHON!" -B -Wall %__SourceDir%\scripts\genEventPipe.py --man %__SourceDir%\vm\ClrEtwAll.man --exc %__SourceDir%\vm\ClrEtwAllMeta.lst --intermediate %__IntermediatesEventingDir%\eventpipe --nonextern || exit /b 1
echo %__MsgPrefix%Laying out ETW event logging interface
"!PYTHON!" -B -Wall %__SourceDir%\scripts\genEtwProvider.py --man %__SourceDir%\vm\ClrEtwAll.man --intermediate %__IntermediatesIncDir% --exc %__SourceDir%\vm\ClrEtwAllMeta.lst || exit /b 1
@@ -448,7 +448,7 @@ if %__BuildCrossArchNative% EQU 1 (
"!PYTHON!" -B -Wall %__SourceDir%\scripts\genEventing.py --inc !__CrossCompIntermediatesIncDir! --dummy !__CrossCompIntermediatesIncDir!\etmdummy.h --man %__SourceDir%\vm\ClrEtwAll.man --nonextern || exit /b 1
echo %__MsgPrefix%Laying out dynamically generated EventPipe Implementation
- "!PYTHON!" -B -Wall %__SourceDir%\scripts\genEventPipe.py --man %__SourceDir%\vm\ClrEtwAll.man --intermediate !__CrossCompIntermediatesEventingDir!\eventpipe --nonextern || exit /b 1
+ "!PYTHON!" -B -Wall %__SourceDir%\scripts\genEventPipe.py --man %__SourceDir%\vm\ClrEtwAll.man --exc %__SourceDir%\vm\ClrEtwAllMeta.lst --intermediate !__CrossCompIntermediatesEventingDir!\eventpipe --nonextern || exit /b 1
echo %__MsgPrefix%Laying out dynamically generated EventSource classes
"!PYTHON!" -B -Wall %__SourceDir%\scripts\genRuntimeEventSources.py --man %__SourceDir%\vm\ClrEtwAll.man --intermediate !__CrossCompIntermediatesEventingDir! || exit /b 1
diff --git a/build.sh b/build.sh
index 7e9ce99124..a24bd89070 100755
--- a/build.sh
+++ b/build.sh
@@ -188,7 +188,7 @@ generate_event_logging_sources()
fi
echo "Laying out dynamically generated EventPipe Implementation"
- $PYTHON -B $__PythonWarningFlags "$__ProjectRoot/src/scripts/genEventPipe.py" --man "$__ProjectRoot/src/vm/ClrEtwAll.man" --intermediate "$__OutputEventingDir/eventpipe"
+ $PYTHON -B $__PythonWarningFlags "$__ProjectRoot/src/scripts/genEventPipe.py" --man "$__ProjectRoot/src/vm/ClrEtwAll.man" --exc "$__ProjectRoot/src/vm/ClrEtwAllMeta.lst" --intermediate "$__OutputEventingDir/eventpipe"
echo "Laying out dynamically generated EventSource classes"
$PYTHON -B $__PythonWarningFlags "$__ProjectRoot/src/scripts/genRuntimeEventSources.py" --man "$__ProjectRoot/src/vm/ClrEtwAll.man" --intermediate "$__OutputEventingDir"
diff --git a/src/scripts/genEtwProvider.py b/src/scripts/genEtwProvider.py
index 79a286a501..89d3119cf4 100644
--- a/src/scripts/genEtwProvider.py
+++ b/src/scripts/genEtwProvider.py
@@ -14,7 +14,7 @@ import argparse
import subprocess
import xml.dom.minidom as DOM
from genEventing import parseTemplateNodes
-from utilities import open_for_update, update_directory
+from utilities import open_for_update, update_directory, parseExclusionList
macroheader_filename = "etwmacros.h"
mcheader_filename = "ClrEtwAll.h"
@@ -102,59 +102,12 @@ def genXplatHeader(intermediate):
#endif //_CLR_XPLAT_EVENTS_H_
""".format(etw_dirname, macroheader_filename, mcheader_filename))
-
-class EventExclusions:
- def __init__(self):
- self.nostack = set()
- self.explicitstack = set()
- self.noclrinstance = set()
-
-def parseExclusionList(exclusion_filename):
- with open(exclusion_filename,'r') as ExclusionFile:
- exclusionInfo = EventExclusions()
-
- for line in ExclusionFile:
- line = line.strip()
-
- #remove comments
- if not line or line.startswith('#'):
- continue
-
- tokens = line.split(':')
- #entries starting with nomac are ignored
- if "nomac" in tokens:
- continue
-
- if len(tokens) > 5:
- raise Exception("Invalid Entry " + line + "in "+ exclusion_filename)
-
- eventProvider = tokens[2]
- eventTask = tokens[1]
- eventSymbol = tokens[4]
-
- if eventProvider == '':
- eventProvider = "*"
- if eventTask == '':
- eventTask = "*"
- if eventSymbol == '':
- eventSymbol = "*"
- entry = eventProvider + ":" + eventTask + ":" + eventSymbol
-
- if tokens[0].lower() == "nostack":
- exclusionInfo.nostack.add(entry)
- if tokens[0].lower() == "stack":
- exclusionInfo.explicitstack.add(entry)
- if tokens[0].lower() == "noclrinstanceid":
- exclusionInfo.noclrinstance.add(entry)
-
- return exclusionInfo
-
def getStackWalkBit(eventProvider, taskName, eventSymbol, stackSet):
for entry in stackSet:
tokens = entry.split(':')
if len(tokens) != 3:
- raise Exception("Error, possible error in the script which introduced the enrty "+ entry)
+ raise Exception("Error, possible error in the script which introduced the entry "+ entry)
eventCond = tokens[0] == eventProvider or tokens[0] == "*"
taskCond = tokens[1] == taskName or tokens[1] == "*"
@@ -164,7 +117,7 @@ def getStackWalkBit(eventProvider, taskName, eventSymbol, stackSet):
return False
return True
-#Add the miscelaneous checks here
+#Add the miscellaneous checks here
def checkConsistency(manifest, exclusion_filename):
tree = DOM.parse(manifest)
exclusionInfo = parseExclusionList(exclusion_filename)
diff --git a/src/scripts/genEventPipe.py b/src/scripts/genEventPipe.py
index 59f5d711fe..f66b54ea28 100644
--- a/src/scripts/genEventPipe.py
+++ b/src/scripts/genEventPipe.py
@@ -3,7 +3,7 @@ from genEventing import *
from genLttngProvider import *
import os
import xml.dom.minidom as DOM
-from utilities import open_for_update
+from utilities import open_for_update, parseExclusionList
stdprolog_cpp = """// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
@@ -73,7 +73,7 @@ def generateMethodSignatureWrite(eventName, template, extern):
return ''.join(sig_pieces)
def generateClrEventPipeWriteEventsImpl(
- providerName, eventNodes, allTemplates, extern):
+ providerName, eventNodes, allTemplates, extern, exclusionList):
providerPrettyName = providerName.replace("Windows-", '')
providerPrettyName = providerPrettyName.replace("Microsoft-", '')
providerPrettyName = providerPrettyName.replace('-', '_')
@@ -153,8 +153,14 @@ def generateClrEventPipeWriteEventsImpl(
eventLevel = eventLevel.replace("win:", "EventPipeEventLevel::")
taskName = eventNode.getAttribute('task')
- initEvent = """ EventPipeEvent%s = EventPipeProvider%s->AddEvent(%s,%s,%s,%s);
-""" % (eventName, providerPrettyName, eventValue, eventKeywordsMask, eventVersion, eventLevel)
+ needStack = "true"
+ for nostackentry in exclusionList.nostack:
+ tokens = nostackentry.split(':')
+ if tokens[2] == eventName:
+ needStack = "false"
+
+ initEvent = """ EventPipeEvent%s = EventPipeProvider%s->AddEvent(%s,%s,%s,%s,%s);
+""" % (eventName, providerPrettyName, eventValue, eventKeywordsMask, eventVersion, eventLevel, needStack)
WriteEventImpl.append(initEvent)
WriteEventImpl.append("}")
@@ -384,7 +390,7 @@ bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size,
helper.close()
def generateEventPipeImplFiles(
- etwmanifest, eventpipe_directory, extern):
+ etwmanifest, eventpipe_directory, extern, exclusionList):
tree = DOM.parse(etwmanifest)
# Find the src directory starting with the assumption that
@@ -460,11 +466,12 @@ bool WriteToBuffer(const T &value, char *&buffer, size_t& offset, size_t& size,
providerName,
eventNodes,
allTemplates,
- extern) + "\n")
+ extern,
+ exclusionList) + "\n")
def generateEventPipeFiles(
- etwmanifest, intermediate, extern):
+ etwmanifest, intermediate, extern, exclusionList):
eventpipe_directory = os.path.join(intermediate, eventpipe_dirname)
tree = DOM.parse(etwmanifest)
@@ -487,7 +494,8 @@ def generateEventPipeFiles(
generateEventPipeImplFiles(
etwmanifest,
eventpipe_directory,
- extern
+ extern,
+ exclusionList
)
import argparse
@@ -502,6 +510,8 @@ def main(argv):
required = parser.add_argument_group('required arguments')
required.add_argument('--man', type=str, required=True,
help='full path to manifest containig the description of events')
+ required.add_argument('--exc', type=str, required=True,
+ help='full path to exclusion list')
required.add_argument('--intermediate', type=str, required=True,
help='full path to eventprovider intermediate directory')
required.add_argument('--nonextern', action='store_true',
@@ -512,10 +522,11 @@ def main(argv):
return 1
sClrEtwAllMan = args.man
+ exclusion_filename = args.exc
intermediate = args.intermediate
extern = not args.nonextern
- generateEventPipeFiles(sClrEtwAllMan, intermediate, extern)
+ generateEventPipeFiles(sClrEtwAllMan, intermediate, extern, parseExclusionList(exclusion_filename))
if __name__ == '__main__':
return_code = main(sys.argv[1:])
diff --git a/src/scripts/utilities.py b/src/scripts/utilities.py
index 7e69f462a9..c4767a43b7 100644
--- a/src/scripts/utilities.py
+++ b/src/scripts/utilities.py
@@ -120,3 +120,49 @@ def update_directory(srcpath, dstpath, recursive=True, destructive=True, shallow
if not os.path.exists(dstdir):
os.makedirs(dstdir)
update_directory(srcdir, dstdir, recursive, destructive, shallow)
+
+class EventExclusions:
+ def __init__(self):
+ self.nostack = set()
+ self.explicitstack = set()
+ self.noclrinstance = set()
+
+def parseExclusionList(exclusion_filename):
+ with open(exclusion_filename,'r') as ExclusionFile:
+ exclusionInfo = EventExclusions()
+
+ for line in ExclusionFile:
+ line = line.strip()
+
+ #remove comments
+ if not line or line.startswith('#'):
+ continue
+
+ tokens = line.split(':')
+ #entries starting with nomac are ignored
+ if "nomac" in tokens:
+ continue
+
+ if len(tokens) > 5:
+ raise Exception("Invalid Entry " + line + "in "+ exclusion_filename)
+
+ eventProvider = tokens[2]
+ eventTask = tokens[1]
+ eventSymbol = tokens[4]
+
+ if eventProvider == '':
+ eventProvider = "*"
+ if eventTask == '':
+ eventTask = "*"
+ if eventSymbol == '':
+ eventSymbol = "*"
+ entry = eventProvider + ":" + eventTask + ":" + eventSymbol
+
+ if tokens[0].lower() == "nostack":
+ exclusionInfo.nostack.add(entry)
+ if tokens[0].lower() == "stack":
+ exclusionInfo.explicitstack.add(entry)
+ if tokens[0].lower() == "noclrinstanceid":
+ exclusionInfo.noclrinstance.add(entry)
+
+ return exclusionInfo \ No newline at end of file
diff --git a/src/vm/eventpipeeventsource.cpp b/src/vm/eventpipeeventsource.cpp
index 20613b8d53..ca62677cde 100644
--- a/src/vm/eventpipeeventsource.cpp
+++ b/src/vm/eventpipeeventsource.cpp
@@ -51,6 +51,7 @@ EventPipeEventSource::EventPipeEventSource()
0, /* keywords */
0, /* eventVersion */
EventPipeEventLevel::LogAlways,
+ false, /* needStack */
pMetadata,
(unsigned int)metadataLength);
diff --git a/src/vm/eventpipeinternal.cpp b/src/vm/eventpipeinternal.cpp
index c02317f491..30a14642c0 100644
--- a/src/vm/eventpipeinternal.cpp
+++ b/src/vm/eventpipeinternal.cpp
@@ -110,7 +110,7 @@ INT_PTR QCALLTYPE EventPipeInternal::DefineEvent(
_ASSERTE(provHandle != NULL);
EventPipeProvider *pProvider = reinterpret_cast<EventPipeProvider *>(provHandle);
- pEvent = pProvider->AddEvent(eventID, keywords, eventVersion, (EventPipeEventLevel)level, (BYTE *)pMetadata, metadataLength);
+ pEvent = pProvider->AddEvent(eventID, keywords, eventVersion, (EventPipeEventLevel)level, /* needStack = */ true, (BYTE *)pMetadata, metadataLength);
_ASSERTE(pEvent != NULL);
END_QCALL;
diff --git a/src/vm/eventpipeprovider.cpp b/src/vm/eventpipeprovider.cpp
index 4630c93acd..4c6eabcf50 100644
--- a/src/vm/eventpipeprovider.cpp
+++ b/src/vm/eventpipeprovider.cpp
@@ -130,19 +130,6 @@ void EventPipeProvider::SetConfiguration(bool providerEnabled, INT64 keywords, E
InvokeCallback(pFilterData);
}
-EventPipeEvent* EventPipeProvider::AddEvent(unsigned int eventID, INT64 keywords, unsigned int eventVersion, EventPipeEventLevel level, BYTE *pMetadata, unsigned int metadataLength)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return AddEvent(eventID, keywords, eventVersion, level, true /* needStack */, pMetadata, metadataLength);
-}
-
EventPipeEvent* EventPipeProvider::AddEvent(unsigned int eventID, INT64 keywords, unsigned int eventVersion, EventPipeEventLevel level, bool needStack, BYTE *pMetadata, unsigned int metadataLength)
{
CONTRACTL
diff --git a/src/vm/eventpipeprovider.h b/src/vm/eventpipeprovider.h
index cf89cf3229..8ae57d9d62 100644
--- a/src/vm/eventpipeprovider.h
+++ b/src/vm/eventpipeprovider.h
@@ -70,17 +70,10 @@ public:
bool EventEnabled(INT64 keywords, EventPipeEventLevel eventLevel) const;
// Create a new event.
- EventPipeEvent* AddEvent(unsigned int eventID, INT64 keywords, unsigned int eventVersion, EventPipeEventLevel level, BYTE *pMetadata = NULL, unsigned int metadataLength = 0);
+ EventPipeEvent* AddEvent(unsigned int eventID, INT64 keywords, unsigned int eventVersion, EventPipeEventLevel level, bool needStack, BYTE *pMetadata = NULL, unsigned int metadataLength = 0);
private:
- // Create a new event, but allow needStack to be specified.
- // In general, we want stack walking to be controlled by the consumer and not the producer of events.
- // However, there are a couple of cases that we know we don't want to do a stackwalk that would affect performance significantly:
- // 1. Sample profiler events: The sample profiler already does a stack walk of the target thread. Doing one of the sampler thread is a waste.
- // 2. Metadata events: These aren't as painful but because we have to keep this functionality around, might as well use it.
- EventPipeEvent* AddEvent(unsigned int eventID, INT64 keywords, unsigned int eventVersion, EventPipeEventLevel level, bool needStack, BYTE *pMetadata = NULL, unsigned int metadataLength = 0);
-
// Add an event to the provider.
void AddEvent(EventPipeEvent &event);