• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_READER_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_TRACE_READER_H_
19 
20 #include <cstddef>
21 #include <cstdint>
22 #include <optional>
23 #include <utility>
24 #include <vector>
25 
26 #include "perfetto/base/status.h"
27 #include "perfetto/ext/base/flat_hash_map.h"
28 #include "src/trace_processor/importers/common/chunked_trace_reader.h"
29 #include "src/trace_processor/importers/proto/multi_machine_trace_manager.h"
30 #include "src/trace_processor/importers/proto/packet_sequence_state_builder.h"
31 #include "src/trace_processor/importers/proto/proto_trace_tokenizer.h"
32 #include "src/trace_processor/storage/trace_storage.h"
33 
34 namespace protozero {
35 struct ConstBytes;
36 }
37 
38 namespace perfetto {
39 
40 namespace protos::pbzero {
41 class TracePacket_Decoder;
42 class TraceConfig_Decoder;
43 }  // namespace protos::pbzero
44 
45 namespace trace_processor {
46 
47 class PacketSequenceState;
48 class TraceProcessorContext;
49 class TraceSorter;
50 class TraceStorage;
51 
52 // Implementation of ChunkedTraceReader for proto traces. Tokenizes a proto
53 // trace into packets, handles parsing of any packets which need to be
54 // handled in trace-order and passes the remainder to TraceSorter to sort
55 // into timestamp order.
56 class ProtoTraceReader : public ChunkedTraceReader {
57  public:
58   // |reader| is the abstract method of getting chunks of size |chunk_size_b|
59   // from a trace file with these chunks parsed into |trace|.
60   explicit ProtoTraceReader(TraceProcessorContext*);
61   ~ProtoTraceReader() override;
62 
63   // ChunkedTraceReader implementation.
64   base::Status Parse(TraceBlobView) override;
65   base::Status NotifyEndOfFile() override;
66 
67   using SyncClockSnapshots = base::FlatHashMap<
68       int64_t,
69       std::pair</*host ts*/ uint64_t, /*client ts*/ uint64_t>>;
70   static base::FlatHashMap<int64_t /*Clock Id*/, int64_t /*Offset*/>
CalculateClockOffsetsForTesting(std::vector<SyncClockSnapshots> & sync_clock_snapshots)71   CalculateClockOffsetsForTesting(
72       std::vector<SyncClockSnapshots>& sync_clock_snapshots) {
73     return CalculateClockOffsets(sync_clock_snapshots);
74   }
75 
76   std::optional<StringId> GetBuiltinClockNameOrNull(int64_t clock_id);
77 
78  private:
79   struct SequenceScopedState {
80     std::optional<PacketSequenceStateBuilder> sequence_state_builder;
81     uint32_t previous_packet_dropped_count = 0;
82     uint32_t needs_incremental_state_total = 0;
83     uint32_t needs_incremental_state_skipped = 0;
84   };
85 
86   using ConstBytes = protozero::ConstBytes;
87   base::Status ParsePacket(TraceBlobView);
88   base::Status TimestampTokenizeAndPushToSorter(TraceBlobView);
89   base::Status ParseServiceEvent(int64_t ts, ConstBytes);
90   base::Status ParseClockSnapshot(ConstBytes blob, uint32_t seq_id);
91   base::Status ParseRemoteClockSync(ConstBytes blob);
92   void HandleIncrementalStateCleared(
93       const protos::pbzero::TracePacket_Decoder&);
94   void HandleFirstPacketOnSequence(uint32_t packet_sequence_id);
95   void HandlePreviousPacketDropped(const protos::pbzero::TracePacket_Decoder&);
96   void ParseTracePacketDefaults(const protos::pbzero::TracePacket_Decoder&,
97                                 TraceBlobView trace_packet_defaults);
98   void ParseInternedData(const protos::pbzero::TracePacket_Decoder&,
99                          TraceBlobView interned_data);
100   void ParseTraceConfig(ConstBytes);
101   void ParseTraceStats(ConstBytes);
102 
103   static base::FlatHashMap<int64_t /*Clock Id*/, int64_t /*Offset*/>
104   CalculateClockOffsets(std::vector<SyncClockSnapshots>&);
105 
GetIncrementalStateForPacketSequence(uint32_t sequence_id)106   PacketSequenceStateBuilder* GetIncrementalStateForPacketSequence(
107       uint32_t sequence_id) {
108     auto& builder = sequence_state_.Find(sequence_id)->sequence_state_builder;
109     if (!builder) {
110       builder = PacketSequenceStateBuilder(context_);
111     }
112     return &*builder;
113   }
114   base::Status ParseExtensionDescriptor(ConstBytes descriptor);
115 
116   TraceProcessorContext* context_;
117 
118   ProtoTraceTokenizer tokenizer_;
119 
120   // Temporary. Currently trace packets do not have a timestamp, so the
121   // timestamp given is latest_timestamp_.
122   int64_t latest_timestamp_ = 0;
123 
124   base::FlatHashMap<uint32_t, SequenceScopedState> sequence_state_;
125   StringId skipped_packet_key_id_;
126   StringId invalid_incremental_state_key_id_;
127 
128   std::vector<TraceBlobView> eof_deferred_packets_;
129   bool received_eof_ = false;
130 };
131 
132 }  // namespace trace_processor
133 }  // namespace perfetto
134 
135 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_TRACE_READER_H_
136