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