• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html>
2<!--
3Copyright (c) 2014 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/tracing/extras/importer/etw/parser.html">
9
10<script>
11'use strict';
12
13/**
14 * @fileoverview Parses processes events in the Windows event trace format.
15 *
16 * The Windows process events are:
17 *
18 * - DCStart: Describes a process that was already running when the trace
19 *    started. ETW automatically generates these events for all running
20 *    processes at the beginning of the trace.
21 * - Start: Describes a process launched during the tracing session.
22 * - End: Describes a process that ended during the tracing session.
23 * - DCEnd: Describes a process that was still running when the trace ended.
24 *
25 * See http://msdn.microsoft.com/library/windows/desktop/aa364092.aspx
26 */
27tr.exportTo('tr.e.importer.etw', function() {
28  var Parser = tr.e.importer.etw.Parser;
29
30  // Constants for Process events.
31  var guid = '3D6FA8D0-FE05-11D0-9DDA-00C04FD7BA7C';
32  var kProcessStartOpcode = 1;
33  var kProcessEndOpcode = 2;
34  var kProcessDCStartOpcode = 3;
35  var kProcessDCEndOpcode = 4;
36  var kProcessDefunctOpcode = 39;
37
38  /**
39   * Parses Windows process trace events.
40   * @constructor
41   */
42  function ProcessParser(importer) {
43    Parser.call(this, importer);
44
45    // Register handlers.
46    importer.registerEventHandler(guid, kProcessStartOpcode,
47        ProcessParser.prototype.decodeStart.bind(this));
48    importer.registerEventHandler(guid, kProcessEndOpcode,
49        ProcessParser.prototype.decodeEnd.bind(this));
50    importer.registerEventHandler(guid, kProcessDCStartOpcode,
51        ProcessParser.prototype.decodeDCStart.bind(this));
52    importer.registerEventHandler(guid, kProcessDCEndOpcode,
53        ProcessParser.prototype.decodeDCEnd.bind(this));
54    importer.registerEventHandler(guid, kProcessDefunctOpcode,
55        ProcessParser.prototype.decodeDefunct.bind(this));
56  }
57
58  ProcessParser.prototype = {
59    __proto__: Parser.prototype,
60
61    decodeFields: function(header, decoder) {
62      if (header.version > 5)
63        throw new Error('Incompatible Process event version.');
64
65      var pageDirectoryBase;
66      if (header.version == 1)
67        pageDirectoryBase = decoder.decodeUInteger(header.is64);
68
69      var uniqueProcessKey;
70      if (header.version >= 2)
71        uniqueProcessKey = decoder.decodeUInteger(header.is64);
72
73      var processId = decoder.decodeUInt32();
74      var parentId = decoder.decodeUInt32();
75
76      var sessionId;
77      var exitStatus;
78      if (header.version >= 1) {
79        sessionId = decoder.decodeUInt32();
80        exitStatus = decoder.decodeInt32();
81      }
82
83      var directoryTableBase;
84      if (header.version >= 3)
85        directoryTableBase = decoder.decodeUInteger(header.is64);
86
87      var flags;
88      if (header.version >= 4)
89        flags = decoder.decodeUInt32();
90
91      var userSID = decoder.decodeSID(header.is64);
92
93      var imageFileName;
94      if (header.version >= 1)
95        imageFileName = decoder.decodeString();
96
97      var commandLine;
98      if (header.version >= 2)
99        commandLine = decoder.decodeW16String();
100
101      var packageFullName;
102      var applicationId;
103      if (header.version >= 4) {
104        packageFullName = decoder.decodeW16String();
105        applicationId = decoder.decodeW16String();
106      }
107
108      var exitTime;
109      if (header.version == 5 && header.opcode == kProcessDefunctOpcode)
110        exitTime = decoder.decodeUInt64ToString();
111
112      return {
113        pageDirectoryBase: pageDirectoryBase,
114        uniqueProcessKey: uniqueProcessKey,
115        processId: processId,
116        parentId: parentId,
117        sessionId: sessionId,
118        exitStatus: exitStatus,
119        directoryTableBase: directoryTableBase,
120        flags: flags,
121        userSID: userSID,
122        imageFileName: imageFileName,
123        commandLine: commandLine,
124        packageFullName: packageFullName,
125        applicationId: applicationId,
126        exitTime: exitTime
127      };
128    },
129
130    decodeStart: function(header, decoder) {
131      var fields = this.decodeFields(header, decoder);
132      var process = this.model.getOrCreateProcess(fields.processId);
133      if (process.hasOwnProperty('has_ended')) {
134        // On Windows, a process ID used by a process could be reused as soon as
135        // the process ends (there is no pid cycling like on Linux). However, in
136        // a short trace, this is unlikely to happen.
137        throw new Error('Process clash detected.');
138      }
139      process.name = fields.imageFileName;
140      return true;
141    },
142
143    decodeEnd: function(header, decoder) {
144      var fields = this.decodeFields(header, decoder);
145      var process = this.model.getOrCreateProcess(fields.processId);
146      process.has_ended = true;
147      return true;
148    },
149
150    decodeDCStart: function(header, decoder) {
151      var fields = this.decodeFields(header, decoder);
152      var process = this.model.getOrCreateProcess(fields.processId);
153      if (process.hasOwnProperty('has_ended'))
154        throw new Error('Process clash detected.');
155      process.name = fields.imageFileName;
156      return true;
157    },
158
159    decodeDCEnd: function(header, decoder) {
160      var fields = this.decodeFields(header, decoder);
161      var process = this.model.getOrCreateProcess(fields.processId);
162      process.has_ended = true;
163      return true;
164    },
165
166    decodeDefunct: function(header, decoder) {
167      var fields = this.decodeFields(header, decoder);
168      // TODO(etienneb): Update the Model with |fields|.
169      return true;
170    }
171
172  };
173
174  Parser.register(ProcessParser);
175
176  return {
177    ProcessParser: ProcessParser
178  };
179});
180</script>
181
182