1 /* 2 * Copyright (C) 2018 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 #ifndef SRC_TRACE_PROCESSOR_PROTO_TRACE_TOKENIZER_H_ 18 #define SRC_TRACE_PROCESSOR_PROTO_TRACE_TOKENIZER_H_ 19 20 #include <stdint.h> 21 22 #include <memory> 23 #include <vector> 24 25 #include "src/trace_processor/chunked_trace_reader.h" 26 #include "src/trace_processor/proto_incremental_state.h" 27 #include "src/trace_processor/trace_processor_impl.h" 28 29 #include "perfetto/trace/trace_packet.pbzero.h" 30 31 namespace perfetto { 32 namespace trace_processor { 33 34 class TraceProcessorContext; 35 class TraceBlobView; 36 class TraceSorter; 37 class TraceStorage; 38 39 // Reads a protobuf trace in chunks and extracts boundaries of trace packets 40 // (or subfields, for the case of ftrace) with their timestamps. 41 class ProtoTraceTokenizer : public ChunkedTraceReader { 42 public: 43 // Scans the beginning of the trace for valid TracePackets to determine if the 44 // trace contains TrackEvents. 45 // 46 // TODO(eseckler): This is a pretty bad hack to enable us to choose a 47 // different sorting window size for traces with TrackEvents. We should 48 // reconsider and redesign our sorting strategy, so that we don't need to 49 // change global trace processor options if TrackEvents are present. 50 static TraceType GuessProtoTraceType(const uint8_t* data, size_t size); 51 52 // |reader| is the abstract method of getting chunks of size |chunk_size_b| 53 // from a trace file with these chunks parsed into |trace|. 54 explicit ProtoTraceTokenizer(TraceProcessorContext*); 55 ~ProtoTraceTokenizer() override; 56 57 // ChunkedTraceReader implementation. 58 bool Parse(std::unique_ptr<uint8_t[]>, size_t size) override; 59 60 private: 61 void ParseInternal(std::unique_ptr<uint8_t[]> owned_buf, 62 uint8_t* data, 63 size_t size); 64 void ParsePacket(TraceBlobView); 65 void HandleIncrementalStateCleared( 66 const protos::pbzero::TracePacket::Decoder& packet_decoder); 67 void HandlePreviousPacketDropped( 68 const protos::pbzero::TracePacket::Decoder& packet_decoder); 69 void ParseInternedData( 70 const protos::pbzero::TracePacket::Decoder& packet_decoder, 71 TraceBlobView interned_data); 72 void ParseThreadDescriptorPacket( 73 const protos::pbzero::TracePacket::Decoder& packet_decoder); 74 void ParseTrackEventPacket( 75 const protos::pbzero::TracePacket::Decoder& packet_decoder, 76 TraceBlobView packet); 77 void ParseFtraceBundle(TraceBlobView); 78 void ParseFtraceEvent(uint32_t cpu, TraceBlobView); 79 80 ProtoIncrementalState::PacketSequenceState* GetIncrementalStateForPacketSequence(uint32_t sequence_id)81 GetIncrementalStateForPacketSequence(uint32_t sequence_id) { 82 if (!incremental_state) 83 incremental_state.reset(new ProtoIncrementalState()); 84 return incremental_state->GetOrCreateStateForPacketSequence(sequence_id); 85 } 86 87 TraceProcessorContext* context_; 88 89 // Used to glue together trace packets that span across two (or more) 90 // Parse() boundaries. 91 std::vector<uint8_t> partial_buf_; 92 93 // Temporary. Currently trace packets do not have a timestamp, so the 94 // timestamp given is latest_timestamp_. 95 int64_t latest_timestamp_ = 0; 96 97 // Stores incremental state and references to interned data, e.g. for track 98 // event protos. 99 std::unique_ptr<ProtoIncrementalState> incremental_state; 100 }; 101 102 } // namespace trace_processor 103 } // namespace perfetto 104 105 #endif // SRC_TRACE_PROCESSOR_PROTO_TRACE_TOKENIZER_H_ 106