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 : // Implementation of call-trace parsing.
16 :
17 : #include "syzygy/trace/parse/parser.h"
18 :
19 : #include "base/logging.h"
20 : #include "syzygy/common/buffer_parser.h"
21 : #include "syzygy/trace/parse/parse_engine_rpc.h"
22 :
23 : namespace trace {
24 : namespace parser {
25 :
26 : using ::common::BinaryBufferParser;
27 :
28 E : Parser::Parser() : active_parse_engine_(NULL) {
29 E : }
30 :
31 E : Parser::~Parser() {
32 E : ignore_result(Close());
33 :
34 E : ParseEngineIter it = parse_engine_set_.begin();
35 E : for (; it != parse_engine_set_.end(); ++it) {
36 E : delete *it;
37 E : }
38 E : parse_engine_set_.clear();
39 E : }
40 :
41 E : void Parser::AddParseEngine(ParseEngine* parse_engine) {
42 E : DCHECK(parse_engine != NULL);
43 E : parse_engine_set_.push_front(parse_engine);
44 E : }
45 :
46 E : bool Parser::Init(ParseEventHandler* event_handler) {
47 E : DCHECK(event_handler != NULL);
48 E : DCHECK(active_parse_engine_ == NULL);
49 :
50 E : ParseEngine* engine = NULL;
51 :
52 : // Create the RPC call-trace parse engine.
53 E : LOG(INFO) << "Initializing RPC call-trace parse engine.";
54 E : engine = new ParseEngineRpc;
55 E : if (engine == NULL) {
56 i : LOG(ERROR) << "Failed to initialize RPC call-trace parse engine.";
57 i : return false;
58 : }
59 E : parse_engine_set_.push_back(engine);
60 :
61 : // Setup the event handler for all of the engines.
62 E : ParseEngineIter it = parse_engine_set_.begin();
63 E : for (; it != parse_engine_set_.end(); ++it) {
64 E : (*it)->set_event_handler(event_handler);
65 E : }
66 :
67 E : return true;
68 E : }
69 :
70 E : bool Parser::error_occurred() const {
71 E : DCHECK(active_parse_engine_ != NULL);
72 E : return active_parse_engine_->error_occurred();
73 E : }
74 :
75 i : void Parser::set_error_occurred(bool value) {
76 i : DCHECK(active_parse_engine_ != NULL);
77 i : active_parse_engine_->set_error_occurred(value);
78 i : }
79 :
80 E : bool Parser::OpenTraceFile(const base::FilePath& trace_file_path) {
81 E : DCHECK(!trace_file_path.empty());
82 :
83 E : if (active_parse_engine_ == NULL && !SetActiveParseEngine(trace_file_path)) {
84 E : return false;
85 : }
86 :
87 E : DCHECK(active_parse_engine_ != NULL);
88 E : return active_parse_engine_->OpenTraceFile(trace_file_path);
89 E : }
90 :
91 E : bool Parser::Consume() {
92 E : if (active_parse_engine_ == NULL) {
93 i : LOG(ERROR) << "No open trace files to consume.";
94 i : return false;
95 : }
96 E : return active_parse_engine_->ConsumeAllEvents();
97 E : }
98 :
99 : const ModuleInformation* Parser::GetModuleInformation(
100 E : uint32 process_id, AbsoluteAddress64 addr) const {
101 E : DCHECK(active_parse_engine_ != NULL);
102 E : return active_parse_engine_->GetModuleInformation(process_id, addr);
103 E : }
104 :
105 E : bool Parser::Close() {
106 E : bool result = true;
107 E : if (active_parse_engine_ != NULL) {
108 E : result = active_parse_engine_->CloseAllTraceFiles();
109 E : active_parse_engine_ = NULL;
110 : }
111 E : return result;
112 E : }
113 :
114 E : bool Parser::SetActiveParseEngine(const base::FilePath& trace_file_path) {
115 E : DCHECK(!trace_file_path.empty());
116 E : DCHECK(active_parse_engine_ == NULL);
117 :
118 E : ParseEngineIter it = parse_engine_set_.begin();
119 E : for (; it != parse_engine_set_.end(); ++it) {
120 E : ParseEngine* engine = *it;
121 E : if (engine->IsRecognizedTraceFile(trace_file_path)) {
122 E : LOG(INFO) << "Using " << engine->name() << " Call-Trace Parser.";
123 E : active_parse_engine_ = engine;
124 E : return true;
125 : }
126 E : }
127 :
128 E : LOG(ERROR) << "Failed to find a parse engine for \""
129 : << trace_file_path.value()
130 : << "\".";
131 :
132 E : return false;
133 E : }
134 :
135 : void ParseEventHandlerImpl::OnProcessStarted(base::Time time,
136 : DWORD process_id,
137 E : const TraceSystemInfo* data) {
138 E : }
139 :
140 E : void ParseEventHandlerImpl::OnProcessEnded(base::Time time, DWORD process_id) {
141 E : }
142 :
143 : void ParseEventHandlerImpl::OnFunctionEntry(
144 : base::Time time,
145 : DWORD process_id,
146 : DWORD thread_id,
147 i : const TraceEnterExitEventData* data) {
148 i : }
149 :
150 : void ParseEventHandlerImpl::OnFunctionExit(
151 : base::Time time,
152 : DWORD process_id,
153 : DWORD thread_id,
154 E : const TraceEnterExitEventData* data) {
155 E : }
156 :
157 : void ParseEventHandlerImpl::OnBatchFunctionEntry(
158 : base::Time time,
159 : DWORD process_id,
160 : DWORD thread_id,
161 i : const TraceBatchEnterData* data) {
162 i : }
163 :
164 : void ParseEventHandlerImpl::OnProcessAttach(
165 : base::Time time,
166 : DWORD process_id,
167 : DWORD thread_id,
168 E : const TraceModuleData* data) {
169 E : }
170 :
171 : void ParseEventHandlerImpl::OnProcessDetach(
172 : base::Time time,
173 : DWORD process_id,
174 : DWORD thread_id,
175 E : const TraceModuleData* data) {
176 E : }
177 :
178 : void ParseEventHandlerImpl::OnThreadAttach(
179 : base::Time time,
180 : DWORD process_id,
181 : DWORD thread_id,
182 E : const TraceModuleData* data) {
183 E : }
184 :
185 : void ParseEventHandlerImpl::OnThreadDetach(
186 : base::Time time,
187 : DWORD process_id,
188 : DWORD thread_id,
189 E : const TraceModuleData* data) {
190 E : }
191 :
192 : void ParseEventHandlerImpl::OnInvocationBatch(
193 : base::Time time,
194 : DWORD process_id,
195 : DWORD thread_id,
196 : size_t num_invocations,
197 i : const TraceBatchInvocationInfo* data) {
198 i : }
199 :
200 : void ParseEventHandlerImpl::OnThreadName(
201 : base::Time time,
202 : DWORD process_id,
203 : DWORD thread_id,
204 i : const base::StringPiece& thread_name) {
205 i : }
206 :
207 : void ParseEventHandlerImpl::OnIndexedFrequency(
208 : base::Time time,
209 : DWORD process_id,
210 : DWORD thread_id,
211 E : const TraceIndexedFrequencyData* data) {
212 E : }
213 :
214 : void ParseEventHandlerImpl::OnDynamicSymbol(
215 i : DWORD process_id, uint32 symbol_id, const base::StringPiece& symbol_name) {
216 i : }
217 :
218 : void ParseEventHandlerImpl::OnSampleData(
219 i : base::Time Time, DWORD process_id, const TraceSampleData* data) {
220 i : }
221 :
222 : void ParseEventHandlerImpl::OnFunctionNameTableEntry(
223 : base::Time Time,
224 : DWORD process_id,
225 i : const TraceFunctionNameTableEntry* data) {
226 i : }
227 :
228 : void ParseEventHandlerImpl::OnStackTrace(
229 : base::Time Time,
230 : DWORD process_id,
231 i : const TraceStackTrace* data) {
232 i : }
233 :
234 : void ParseEventHandlerImpl::OnDetailedFunctionCall(
235 : base::Time Time,
236 : DWORD process_id,
237 : DWORD thread_id,
238 i : const TraceDetailedFunctionCall* data) {
239 i : }
240 :
241 : void ParseEventHandlerImpl::OnComment(
242 : base::Time time,
243 : DWORD process_id,
244 i : const TraceComment* data) {
245 i : }
246 :
247 : } // namespace parser
248 : } // namespace trace
|