• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "src/trace_processor/forwarding_trace_parser.h"
18 
19 #include <memory>
20 #include <optional>
21 
22 #include "perfetto/base/logging.h"
23 #include "perfetto/base/status.h"
24 #include "perfetto/ext/base/status_or.h"
25 #include "src/trace_processor/importers/common/chunked_trace_reader.h"
26 #include "src/trace_processor/importers/common/process_tracker.h"
27 #include "src/trace_processor/importers/proto/proto_trace_reader.h"
28 #include "src/trace_processor/sorter/trace_sorter.h"
29 #include "src/trace_processor/trace_reader_registry.h"
30 #include "src/trace_processor/types/trace_processor_context.h"
31 #include "src/trace_processor/util/status_macros.h"
32 #include "src/trace_processor/util/trace_type.h"
33 
34 namespace perfetto {
35 namespace trace_processor {
36 namespace {
37 
ConvertSortingMode(SortingMode sorting_mode)38 TraceSorter::SortingMode ConvertSortingMode(SortingMode sorting_mode) {
39   switch (sorting_mode) {
40     case SortingMode::kDefaultHeuristics:
41     case SortingMode::kForceFlushPeriodWindowedSort:
42       return TraceSorter::SortingMode::kDefault;
43     case SortingMode::kForceFullSort:
44       return TraceSorter::SortingMode::kFullSort;
45   }
46   PERFETTO_FATAL("For GCC");
47 }
48 
GetMinimumSortingMode(TraceType trace_type,const TraceProcessorContext & context)49 std::optional<TraceSorter::SortingMode> GetMinimumSortingMode(
50     TraceType trace_type,
51     const TraceProcessorContext& context) {
52   switch (trace_type) {
53     case kNinjaLogTraceType:
54     case kSystraceTraceType:
55     case kGzipTraceType:
56     case kCtraceTraceType:
57     case kZipFile:
58       return std::nullopt;
59 
60     case kPerfDataTraceType:
61       return TraceSorter::SortingMode::kDefault;
62 
63     case kUnknownTraceType:
64     case kJsonTraceType:
65     case kFuchsiaTraceType:
66       return TraceSorter::SortingMode::kFullSort;
67 
68     case kProtoTraceType:
69       return ConvertSortingMode(context.config.sorting_mode);
70   }
71   PERFETTO_FATAL("For GCC");
72 }
73 
74 }  // namespace
75 
ForwardingTraceParser(TraceProcessorContext * context)76 ForwardingTraceParser::ForwardingTraceParser(TraceProcessorContext* context)
77     : context_(context) {}
78 
~ForwardingTraceParser()79 ForwardingTraceParser::~ForwardingTraceParser() {}
80 
Init(const TraceBlobView & blob)81 base::Status ForwardingTraceParser::Init(const TraceBlobView& blob) {
82   PERFETTO_CHECK(!reader_);
83 
84   TraceType trace_type;
85   {
86     auto scoped_trace = context_->storage->TraceExecutionTimeIntoStats(
87         stats::guess_trace_type_duration_ns);
88     trace_type = GuessTraceType(blob.data(), blob.size());
89     context_->trace_type = trace_type;
90   }
91 
92   if (trace_type == kUnknownTraceType) {
93     // If renaming this error message don't remove the "(ERR:fmt)" part.
94     // The UI's error_dialog.ts uses it to make the dialog more graceful.
95     return base::ErrStatus("Unknown trace type provided (ERR:fmt)");
96   }
97 
98   base::StatusOr<std::unique_ptr<ChunkedTraceReader>> reader_or =
99       context_->reader_registry->CreateTraceReader(trace_type);
100   if (!reader_or.ok()) {
101     return reader_or.status();
102   }
103   reader_ = std::move(*reader_or);
104 
105   PERFETTO_DLOG("%s detected", ToString(trace_type));
106   UpdateSorterForTraceType(trace_type);
107 
108   // TODO(b/334978369) Make sure kProtoTraceType and kSystraceTraceType are
109   // parsed first so that we do not get issues with
110   // SetPidZeroIsUpidZeroIdleProcess()
111   if (trace_type == kProtoTraceType || trace_type == kSystraceTraceType) {
112     context_->process_tracker->SetPidZeroIsUpidZeroIdleProcess();
113   }
114 
115   return base::OkStatus();
116 }
117 
UpdateSorterForTraceType(TraceType trace_type)118 void ForwardingTraceParser::UpdateSorterForTraceType(TraceType trace_type) {
119   std::optional<TraceSorter::SortingMode> minimum_sorting_mode =
120       GetMinimumSortingMode(trace_type, *context_);
121   if (!minimum_sorting_mode.has_value()) {
122     return;
123   }
124 
125   if (!context_->sorter) {
126     context_->sorter.reset(new TraceSorter(context_, *minimum_sorting_mode));
127   }
128 
129   switch (context_->sorter->sorting_mode()) {
130     case TraceSorter::SortingMode::kDefault:
131       PERFETTO_CHECK(minimum_sorting_mode ==
132                      TraceSorter::SortingMode::kDefault);
133       break;
134     case TraceSorter::SortingMode::kFullSort:
135       break;
136   }
137 }
138 
Parse(TraceBlobView blob)139 base::Status ForwardingTraceParser::Parse(TraceBlobView blob) {
140   // If this is the first Parse() call, guess the trace type and create the
141   // appropriate parser.
142   if (!reader_) {
143     RETURN_IF_ERROR(Init(blob));
144   }
145 
146   return reader_->Parse(std::move(blob));
147 }
148 
NotifyEndOfFile()149 void ForwardingTraceParser::NotifyEndOfFile() {
150   reader_->NotifyEndOfFile();
151 }
152 
153 }  // namespace trace_processor
154 }  // namespace perfetto
155