1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // A utility for controlling call-traces from the command-line.
16 : #include <iostream>
17 : #include "base/at_exit.h"
18 : #include "base/command_line.h"
19 : #include "base/logging.h"
20 : #include "syzygy/trace/etw_control/call_trace_control.h"
21 :
22 m : static const char kUsage[] =
23 m : "Usage: call_trace_control [command] [options]\n"
24 m : "Commands:\n"
25 m : " start: start the call-trace, creating the ETW logs.\n"
26 m : " query: query the call-trace status.\n"
27 m : " stop: stop the call-trace, flushing and closing the ETW logs.\n"
28 m : "\n"
29 m : "Options to 'start':\n"
30 m : " --append: Append to the ETW log files rather than overwriting them.\n"
31 m : " --call-trace-file: Path to call-trace ETW log file.\n"
32 m : " Defaults to 'call_trace.etl' in the current working directory.\n"
33 m : " --chrome-file: Path to Chrome ETW log file.\n"
34 m : " If not specified, does not enable Chrome ETW logging.\n"
35 m : " --min-buffers: The minimum number of buffers to use for call-trace.\n"
36 m : " Augment this from the defaults if seeing lost events.\n"
37 m : " --kernel-file: Path to kernel ETW log file.\n"
38 m : " Defaults to 'kernel.etl' in the current working directory.\n"
39 m : " --kernel-flags: Flags to pass to kernel ETW logger (numeric).\n"
40 m : " Defaults to PROCESS|THREAD|IMAGE_LOAD|DISK_IO|DISK_FILE_IO|\n"
41 m : " MEMORY_PAGE_FAULTS|MEMORY_HARD_FAULTS|FILE_IO.\n";
42 :
43 m : int Usage() {
44 m : std::cout << kUsage;
45 m : return 1;
46 m : }
47 :
48 m : enum Command {
49 m : kStart,
50 m : kQuery,
51 m : kStop,
52 m : };
53 :
54 m : struct Options {
55 m : Command command;
56 m : };
57 :
58 m : bool ParseOptions(Options* options) {
59 m : DCHECK(options != NULL);
60 :
61 m : CommandLine* cmd_line = CommandLine::ForCurrentProcess();
62 :
63 m : if (cmd_line->HasSwitch("help") || cmd_line->HasSwitch("h")) {
64 m : Usage();
65 m : return false;
66 m : }
67 :
68 m : if (cmd_line->GetArgs().size() == 0) {
69 m : LOG(ERROR) << "Must specify a command.";
70 m : return false;
71 m : }
72 :
73 m : if (cmd_line->GetArgs().size() > 1) {
74 m : LOG(ERROR) << "Can only specify one command.";
75 m : return false;
76 m : }
77 :
78 m : if (cmd_line->GetArgs()[0] == L"start") {
79 m : options->command = kStart;
80 m : } else if (cmd_line->GetArgs()[0] == L"query") {
81 m : options->command = kQuery;
82 m : } else if (cmd_line->GetArgs()[0] == L"stop") {
83 m : options->command = kStop;
84 m : } else {
85 m : LOG(ERROR) << "Unknown command: " << cmd_line->GetArgs()[0] << ".";
86 m : return false;
87 m : }
88 :
89 m : return true;
90 m : }
91 :
92 m : int main(int argc, char** argv) {
93 m : base::AtExitManager at_exit;
94 m : CommandLine::Init(argc, argv);
95 :
96 m : if (!logging::InitLogging(L"", logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
97 m : logging::DONT_LOCK_LOG_FILE, logging::APPEND_TO_OLD_LOG_FILE,
98 m : logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS)) {
99 m : return 1;
100 m : }
101 :
102 m : Options options;
103 m : if (!ParseOptions(&options))
104 m : return 1;
105 :
106 : // Call the command we care about.
107 m : bool success = false;
108 m : switch (options.command) {
109 m : case kStart: {
110 m : success = StartCallTraceImpl();
111 m : break;
112 m : }
113 :
114 m : case kQuery: {
115 m : success = QueryCallTraceImpl();
116 m : break;
117 m : }
118 :
119 m : case kStop: {
120 m : success = StopCallTraceImpl();
121 m : break;
122 m : }
123 :
124 m : default: {
125 m : NOTREACHED() << "Unexpected command.";
126 m : }
127 m : }
128 :
129 m : return success ? 0 : 1;
130 m : }
|