• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
18 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
19 
20 #include <stddef.h>
21 #include <memory>
22 #include <optional>
23 #include <tuple>
24 
25 #include "perfetto/base/export.h"
26 #include "perfetto/base/logging.h"
27 #include "perfetto/ext/tracing/core/slice.h"
28 
29 namespace perfetto {
30 
31 // A wrapper around a byte buffer that contains a protobuf-encoded TracePacket
32 // (see trace_packet.proto). The TracePacket is decoded only if the Consumer
33 // requests that. This is to allow Consumer(s) to just stream the packet over
34 // the network or save it to a file without wasting time decoding it and without
35 // needing to depend on libprotobuf or the trace_packet.pb.h header.
36 // If the packets are saved / streamed and not just consumed locally, consumers
37 // should ensure to preserve the unknown fields in the proto. A consumer, in
38 // fact, might have an older version .proto which is newer on the producer.
39 class PERFETTO_EXPORT_COMPONENT TracePacket {
40  public:
41   using const_iterator = Slices::const_iterator;
42 
43   // The field id of protos::Trace::packet, static_assert()-ed in the unittest.
44   static constexpr uint32_t kPacketFieldNumber = 1;
45 
46   // Maximum size of the preamble returned by GetProtoPreamble().
47   static constexpr size_t kMaxPreambleBytes = 8;
48 
49   TracePacket();
50   ~TracePacket();
51   TracePacket(TracePacket&&) noexcept;
52   TracePacket& operator=(TracePacket&&);
53 
54   // Accesses all the raw slices in the packet, for saving them to file/network.
slices()55   const Slices& slices() const { return slices_; }
56 
57   // Mutator, used only by the service and tests.
58   void AddSlice(Slice);
59 
60   // Does not copy / take ownership of the memory of the slice. The TracePacket
61   // will be valid only as long as the original buffer is valid.
62   void AddSlice(const void* start, size_t size);
63 
64   // Total size of all slices.
size()65   size_t size() const { return size_; }
66 
67   // Generates a protobuf preamble suitable to represent this packet as a
68   // repeated field within a root trace.proto message.
69   // Returns a pointer to a buffer, owned by this class, containing the preamble
70   // and its size.
71   std::tuple<char*, size_t> GetProtoPreamble();
72 
73   // Returns the raw protobuf bytes of the slices, all stitched together into
74   // a string. Only for testing.
75   std::string GetRawBytesForTesting();
76 
77   // Remembers the buffer index where this packet was taken from. This is
78   // usually populated for packets from a TraceBuffer, not synthetic ones.
buffer_index_for_stats()79   std::optional<uint32_t> buffer_index_for_stats() const {
80     if (buffer_index_for_stats_ == 0)
81       return std::nullopt;
82     return buffer_index_for_stats_ - 1;
83   }
set_buffer_index_for_stats(uint32_t v)84   void set_buffer_index_for_stats(uint32_t v) {
85     buffer_index_for_stats_ = v + 1;
86   }
87 
88  private:
89   TracePacket(const TracePacket&) = delete;
90   TracePacket& operator=(const TracePacket&) = delete;
91 
92   Slices slices_;     // Not owned.
93   size_t size_ = 0;   // SUM(slice.size for slice in slices_).
94 
95   // Internally we store index+1, and use 0 for the "not set" case.
96   uint32_t buffer_index_for_stats_ = 0;
97   char preamble_[kMaxPreambleBytes];  // Deliberately not initialized.
98 
99   // Remember to update the move operators and their unittest if adding new
100   // fields. ConsumerIPCClientImpl::OnReadBuffersResponse() relies on
101   // std::move(TracePacket) to clear up the moved-from instance.
102 };
103 
104 }  // namespace perfetto
105 
106 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
107