Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(634)

Unified Diff: tools/isolate/trace_inputs.py

Issue 10545098: Implement parallel support on LogmanTrace on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tools/isolate/trace_inputs_smoke_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/isolate/trace_inputs.py
diff --git a/tools/isolate/trace_inputs.py b/tools/isolate/trace_inputs.py
index 515199f59731446eee88a113471f5a9abda36535..984a7b6a1637f1ea5f38983a332e1d18aa311807 100755
--- a/tools/isolate/trace_inputs.py
+++ b/tools/isolate/trace_inputs.py
@@ -2198,10 +2198,49 @@ class LogmanTrace(ApiBase):
NULL_GUID = '{00000000-0000-0000-0000-000000000000}'
USER_DATA = 19
- def trace(self, cmd, cwd, tracename, output):
- """Uses logman.exe to start and stop the NT Kernel Logger while the
- executable to be traced is run.
+ def __init__(self, logname):
+ """Starts the log collection.
+
+ Requires administrative access. logman.exe is synchronous so no need for a
+ "warmup" call. 'Windows Kernel Trace' is *localized* so use its GUID
+ instead. The GUID constant name is SystemTraceControlGuid. Lovely.
+
+ One can get the list of potentially interesting providers with:
+ "logman query providers | findstr /i file"
"""
+ super(LogmanTrace.Tracer, self).__init__(logname)
+ self._script = os.path.join(BASE_DIR, 'trace_child_process.py')
+ cmd_start = [
+ 'logman.exe',
+ 'start',
+ 'NT Kernel Logger',
+ '-p', '{9e814aad-3204-11d2-9a82-006008a86939}',
+ # splitio,fileiocompletion,syscall,file,cswitch,img
+ '(process,fileio,thread)',
+ '-o', self._logname + '.etl',
+ '-ets', # Send directly to kernel
+ # Values extracted out of thin air.
+ # Event Trace Session buffer size in kb.
+ '-bs', '10240',
+ # Number of Event Trace Session buffers.
+ '-nb', '16', '256',
+ ]
+ logging.debug('Running: %s' % cmd_start)
+ try:
+ subprocess.check_call(
+ cmd_start,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError, e:
+ if e.returncode == -2147024891:
+ print >> sys.stderr, 'Please restart with an elevated admin prompt'
+ elif e.returncode == -2144337737:
+ print >> sys.stderr, (
+ 'A kernel trace was already running, stop it and try again')
+ raise
+
+ def trace(self, cmd, cwd, tracename, output):
logging.info('trace(%s, %s, %s, %s)' % (cmd, cwd, tracename, output))
with self._lock:
if not self._initialized:
@@ -2217,32 +2256,28 @@ class LogmanTrace(ApiBase):
stdout = subprocess.PIPE
stderr = subprocess.STDOUT
- # 1. Start the log collection.
- self._start_log(self._logname + '.etl')
-
- # 2. Run the child process.
+ # Run the child process.
logging.debug('Running: %s' % cmd)
- try:
- # Use trace_child_process.py so we have a clear pid owner. Since
- # trace_inputs.py can be used as a library and could trace mulitple
- # processes simultaneously, it makes it more complex if the executable
- # to be traced is executed directly here. It also solves issues related
- # to logman.exe that needs to be executed to control the kernel trace.
- child_cmd = [
- sys.executable,
- os.path.join(BASE_DIR, 'trace_child_process.py'),
- ]
- child = subprocess.Popen(
- child_cmd + cmd,
- cwd=cwd,
- stdin=subprocess.PIPE,
- stdout=stdout,
- stderr=stderr)
- logging.debug('Started child pid: %d' % child.pid)
- out = child.communicate()[0]
- finally:
- # 3. Stop the log collection.
- self._stop_log()
+ # Use trace_child_process.py so we have a clear pid owner. Since
+ # trace_inputs.py can be used as a library and could trace mulitple
+ # processes simultaneously, it makes it more complex if the executable to
+ # be traced is executed directly here. It also solves issues related to
+ # logman.exe that needs to be executed to control the kernel trace.
+ child_cmd = [
+ sys.executable,
+ self._script,
+ tracename,
+ ]
+ child = subprocess.Popen(
+ child_cmd + cmd,
+ cwd=cwd,
+ stdin=subprocess.PIPE,
+ stdout=stdout,
+ stderr=stderr)
+ logging.debug('Started child pid: %d' % child.pid)
+ out = child.communicate()[0]
+ # This doesn't mean all the grand-children are done. Sadly, we don't have
+ # a good way to determine that.
with self._lock:
assert tracename not in (i['trace'] for i in self._traces)
@@ -2256,56 +2291,35 @@ class LogmanTrace(ApiBase):
return child.returncode, out
- @classmethod
- def _start_log(cls, etl):
- """Starts the log collection.
-
- One can get the list of potentially interesting providers with:
- "logman query providers | findstr /i file"
+ def close(self, _timeout=None):
+ """Stops the kernel log collection and converts the traces to text
+ representation.
"""
- cmd_start = [
- 'logman.exe',
- 'start',
- 'NT Kernel Logger',
- '-p', '{9e814aad-3204-11d2-9a82-006008a86939}',
- # splitio,fileiocompletion,syscall,file,cswitch,img
- '(process,fileio,thread)',
- '-o', etl,
- '-ets', # Send directly to kernel
- # Values extracted out of thin air.
- '-bs', '1024',
- '-nb', '200', '512',
- ]
- logging.debug('Running: %s' % cmd_start)
- try:
+ with self._lock:
+ if not self._initialized:
+ raise TracingFailure(
+ 'Called Tracer.close() on an unitialized object',
+ None, None, None)
+ # Save metadata, add 'format' key..
+ data = {
+ 'format': 'csv',
+ 'traces': self._traces,
+ }
+ write_json(self._logname, data, False)
+
+ cmd_stop = [
+ 'logman.exe',
+ 'stop',
+ 'NT Kernel Logger',
+ '-ets', # Sends the command directly to the kernel.
+ ]
+ logging.debug('Running: %s' % cmd_stop)
subprocess.check_call(
- cmd_start,
+ cmd_stop,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
- except subprocess.CalledProcessError, e:
- if e.returncode == -2147024891:
- print >> sys.stderr, 'Please restart with an elevated admin prompt'
- elif e.returncode == -2144337737:
- print >> sys.stderr, (
- 'A kernel trace was already running, stop it and try again')
- raise
-
- @staticmethod
- def _stop_log():
- """Stops the kernel log collection."""
- cmd_stop = [
- 'logman.exe',
- 'stop',
- 'NT Kernel Logger',
- '-ets', # Sends the command directly to the kernel.
- ]
- logging.debug('Running: %s' % cmd_stop)
- subprocess.check_call(
- cmd_stop,
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
+ self._initialized = False
def post_process_log(self):
"""Converts the .etl file into .csv then into .json."""
@@ -2487,8 +2501,7 @@ class LogmanTrace(ApiBase):
data = read_json(logname)
lines = read_json(logname + '.json')
out = []
- for index, item in enumerate(data['traces']):
- print >> sys.stderr, ('%d out of %d' % (index, len(data['traces'])))
+ for item in data['traces']:
context = cls.Context(blacklist_more, item['pid'])
for line in lines:
context.on_line(line)
« no previous file with comments | « no previous file | tools/isolate/trace_inputs_smoke_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698