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_IMPORTERS_PROTO_PROTO_TRACE_TOKENIZER_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_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/importers/gzip/gzip_utils.h"
27 #include "src/trace_processor/importers/proto/proto_incremental_state.h"
28 #include "src/trace_processor/trace_blob_view.h"
29 
30 namespace protozero {
31 struct ConstBytes;
32 }
33 
34 namespace perfetto {
35 
36 namespace protos {
37 namespace pbzero {
38 class TracePacket_Decoder;
39 }  // namespace pbzero
40 }  // namespace protos
41 
42 namespace trace_processor {
43 
44 class PacketSequenceState;
45 class TraceProcessorContext;
46 class TraceSorter;
47 class TraceStorage;
48 
49 // Reads a protobuf trace in chunks and extracts boundaries of trace packets
50 // (or subfields, for the case of ftrace) with their timestamps.
51 class ProtoTraceTokenizer : public ChunkedTraceReader {
52  public:
53   // |reader| is the abstract method of getting chunks of size |chunk_size_b|
54   // from a trace file with these chunks parsed into |trace|.
55   explicit ProtoTraceTokenizer(TraceProcessorContext*);
56   ~ProtoTraceTokenizer() override;
57 
58   // ChunkedTraceReader implementation.
59   util::Status Parse(std::unique_ptr<uint8_t[]>, size_t size) override;
60   void NotifyEndOfFile() override;
61 
62  private:
63   using ConstBytes = protozero::ConstBytes;
64   util::Status ParseInternal(std::unique_ptr<uint8_t[]> owned_buf,
65                              uint8_t* data,
66                              size_t size);
67   util::Status ParsePacket(TraceBlobView);
68   util::Status ParseClockSnapshot(ConstBytes blob, uint32_t seq_id);
69   void HandleIncrementalStateCleared(
70       const protos::pbzero::TracePacket_Decoder&);
71   void HandlePreviousPacketDropped(const protos::pbzero::TracePacket_Decoder&);
72   void ParseTracePacketDefaults(const protos::pbzero::TracePacket_Decoder&,
73                                 TraceBlobView trace_packet_defaults);
74   void ParseInternedData(const protos::pbzero::TracePacket_Decoder&,
75                          TraceBlobView interned_data);
GetIncrementalStateForPacketSequence(uint32_t sequence_id)76   PacketSequenceState* GetIncrementalStateForPacketSequence(
77       uint32_t sequence_id) {
78     if (!incremental_state)
79       incremental_state.reset(new ProtoIncrementalState(context_));
80     return incremental_state->GetOrCreateStateForPacketSequence(sequence_id);
81   }
82 
83   TraceProcessorContext* context_;
84 
85   // Used to glue together trace packets that span across two (or more)
86   // Parse() boundaries.
87   std::vector<uint8_t> partial_buf_;
88 
89   // Temporary. Currently trace packets do not have a timestamp, so the
90   // timestamp given is latest_timestamp_.
91   int64_t latest_timestamp_ = 0;
92 
93   // Stores incremental state and references to interned data, e.g. for track
94   // event protos.
95   std::unique_ptr<ProtoIncrementalState> incremental_state;
96 
97   // Allows support for compressed trace packets.
98   GzipDecompressor decompressor_;
99 };
100 
101 }  // namespace trace_processor
102 }  // namespace perfetto
103 
104 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_TRACE_TOKENIZER_H_
105