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/trace_processor_storage_impl.h" 18 #include <memory> 19 20 #include "perfetto/base/logging.h" 21 #include "perfetto/ext/base/uuid.h" 22 #include "src/trace_processor/forwarding_trace_parser.h" 23 #include "src/trace_processor/importers/common/args_tracker.h" 24 #include "src/trace_processor/importers/common/args_translation_table.h" 25 #include "src/trace_processor/importers/common/async_track_set_tracker.h" 26 #include "src/trace_processor/importers/common/clock_converter.h" 27 #include "src/trace_processor/importers/common/clock_tracker.h" 28 #include "src/trace_processor/importers/common/event_tracker.h" 29 #include "src/trace_processor/importers/common/flow_tracker.h" 30 #include "src/trace_processor/importers/common/machine_tracker.h" 31 #include "src/trace_processor/importers/common/mapping_tracker.h" 32 #include "src/trace_processor/importers/common/metadata_tracker.h" 33 #include "src/trace_processor/importers/common/process_track_translation_table.h" 34 #include "src/trace_processor/importers/common/process_tracker.h" 35 #include "src/trace_processor/importers/common/sched_event_tracker.h" 36 #include "src/trace_processor/importers/common/slice_tracker.h" 37 #include "src/trace_processor/importers/common/slice_translation_table.h" 38 #include "src/trace_processor/importers/common/stack_profile_tracker.h" 39 #include "src/trace_processor/importers/common/track_tracker.h" 40 #include "src/trace_processor/importers/perf/dso_tracker.h" 41 #include "src/trace_processor/importers/proto/chrome_track_event.descriptor.h" 42 #include "src/trace_processor/importers/proto/default_modules.h" 43 #include "src/trace_processor/importers/proto/packet_analyzer.h" 44 #include "src/trace_processor/importers/proto/perf_sample_tracker.h" 45 #include "src/trace_processor/importers/proto/proto_importer_module.h" 46 #include "src/trace_processor/importers/proto/proto_trace_parser_impl.h" 47 #include "src/trace_processor/importers/proto/proto_trace_reader.h" 48 #include "src/trace_processor/importers/proto/track_event.descriptor.h" 49 #include "src/trace_processor/sorter/trace_sorter.h" 50 #include "src/trace_processor/trace_reader_registry.h" 51 #include "src/trace_processor/util/descriptors.h" 52 53 namespace perfetto { 54 namespace trace_processor { 55 TraceProcessorStorageImpl(const Config & cfg)56TraceProcessorStorageImpl::TraceProcessorStorageImpl(const Config& cfg) 57 : context_({cfg, std::make_shared<TraceStorage>(cfg)}) { 58 context_.reader_registry->RegisterTraceReader<ProtoTraceReader>( 59 kProtoTraceType); 60 context_.proto_trace_parser = 61 std::make_unique<ProtoTraceParserImpl>(&context_); 62 RegisterDefaultModules(&context_); 63 } 64 ~TraceProcessorStorageImpl()65TraceProcessorStorageImpl::~TraceProcessorStorageImpl() {} 66 Parse(TraceBlobView blob)67util::Status TraceProcessorStorageImpl::Parse(TraceBlobView blob) { 68 if (blob.size() == 0) 69 return util::OkStatus(); 70 if (unrecoverable_parse_error_) 71 return util::ErrStatus( 72 "Failed unrecoverably while parsing in a previous Parse call"); 73 if (!context_.chunk_reader) 74 context_.chunk_reader.reset(new ForwardingTraceParser(&context_)); 75 76 auto scoped_trace = context_.storage->TraceExecutionTimeIntoStats( 77 stats::parse_trace_duration_ns); 78 79 if (hash_input_size_remaining_ > 0 && !context_.uuid_found_in_trace) { 80 const size_t hash_size = std::min(hash_input_size_remaining_, blob.size()); 81 hash_input_size_remaining_ -= hash_size; 82 83 trace_hash_.Update(reinterpret_cast<const char*>(blob.data()), hash_size); 84 base::Uuid uuid(static_cast<int64_t>(trace_hash_.digest()), 0); 85 const StringId id_for_uuid = 86 context_.storage->InternString(base::StringView(uuid.ToPrettyString())); 87 context_.metadata_tracker->SetMetadata(metadata::trace_uuid, 88 Variadic::String(id_for_uuid)); 89 } 90 91 util::Status status = context_.chunk_reader->Parse(std::move(blob)); 92 unrecoverable_parse_error_ |= !status.ok(); 93 return status; 94 } 95 Flush()96void TraceProcessorStorageImpl::Flush() { 97 if (unrecoverable_parse_error_) 98 return; 99 100 if (context_.sorter) 101 context_.sorter->ExtractEventsForced(); 102 context_.args_tracker->Flush(); 103 } 104 NotifyEndOfFile()105void TraceProcessorStorageImpl::NotifyEndOfFile() { 106 if (unrecoverable_parse_error_ || !context_.chunk_reader) 107 return; 108 Flush(); 109 context_.chunk_reader->NotifyEndOfFile(); 110 // NotifyEndOfFile might have pushed packets to the sorter. 111 Flush(); 112 for (std::unique_ptr<ProtoImporterModule>& module : context_.modules) { 113 module->NotifyEndOfFile(); 114 } 115 if (context_.content_analyzer) { 116 PacketAnalyzer::Get(&context_)->NotifyEndOfFile(); 117 } 118 context_.event_tracker->FlushPendingEvents(); 119 context_.slice_tracker->FlushPendingSlices(); 120 context_.args_tracker->Flush(); 121 context_.process_tracker->NotifyEndOfFile(); 122 if (context_.perf_dso_tracker) { 123 perf_importer::DsoTracker::GetOrCreate(&context_).SymbolizeFrames(); 124 } 125 } 126 DestroyContext()127void TraceProcessorStorageImpl::DestroyContext() { 128 TraceProcessorContext context; 129 context.storage = std::move(context_.storage); 130 131 // TODO(b/309623584): Decouple from storage and remove from here. This 132 // function should only move storage and delete everything else. 133 context.heap_graph_tracker = std::move(context_.heap_graph_tracker); 134 context.clock_converter = std::move(context_.clock_converter); 135 // "to_ftrace" textual converter of the "raw" table requires remembering the 136 // kernel version (inside system_info_tracker) to know how to textualise 137 // sched_switch.prev_state bitflags. 138 context.system_info_tracker = std::move(context_.system_info_tracker); 139 140 context_ = std::move(context); 141 142 // TODO(chinglinyu): also need to destroy secondary contextes. 143 } 144 145 } // namespace trace_processor 146 } // namespace perfetto 147