1 /* 2 * Copyright (C) 2024 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 #include "src/trace_redaction/collect_system_info.h" 18 19 #include "perfetto/protozero/field.h" 20 21 #include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h" 22 #include "protos/perfetto/trace/ps/process_tree.pbzero.h" 23 24 namespace perfetto::trace_redaction { 25 Begin(Context * context) const26base::Status CollectSystemInfo::Begin(Context* context) const { 27 // Other primitives are allows to push more data into the system info (e.g. 28 // another source of pids). 29 if (!context->system_info.has_value()) { 30 context->system_info.emplace(); 31 } 32 33 return base::OkStatus(); 34 } 35 Collect(const protos::pbzero::TracePacket::Decoder & packet,Context * context) const36base::Status CollectSystemInfo::Collect( 37 const protos::pbzero::TracePacket::Decoder& packet, 38 Context* context) const { 39 auto* system_info = &context->system_info.value(); 40 41 PERFETTO_DCHECK(system_info); // See Begin() 42 43 if (packet.has_ftrace_events()) { 44 return OnFtraceEvents(packet.ftrace_events(), context); 45 } 46 47 return base::OkStatus(); 48 } 49 OnFtraceEvents(protozero::ConstBytes bytes,Context * context) const50base::Status CollectSystemInfo::OnFtraceEvents(protozero::ConstBytes bytes, 51 Context* context) const { 52 protozero::ProtoDecoder decoder(bytes); 53 54 auto cpu = 55 decoder.FindField(protos::pbzero::FtraceEventBundle::kCpuFieldNumber); 56 57 if (!cpu.valid()) { 58 return base::ErrStatus( 59 "BuildSyntheticThreads: missing FtraceEventBundle::kCpu."); 60 } 61 62 if (cpu.valid()) { 63 context->system_info->ReserveCpu(cpu.as_uint32()); 64 } 65 66 return base::OkStatus(); 67 } 68 Build(Context * context) const69base::Status BuildSyntheticThreads::Build(Context* context) const { 70 if (!context->system_info.has_value()) { 71 return base::ErrStatus("BuildSyntheticThreads: missing system info."); 72 } 73 74 if (context->synthetic_process) { 75 return base::ErrStatus( 76 "BuildSyntheticThreads: synthetic threads were already initialized."); 77 } 78 79 auto& system_info = context->system_info.value(); 80 81 // Add an extra tid for the main thread. 82 std::vector<int32_t> tids(system_info.cpu_count() + 1); 83 84 for (uint32_t i = 0; i < tids.size(); ++i) { 85 tids[i] = system_info.AllocateSynthThread(); 86 } 87 88 context->synthetic_process = std::make_unique<SyntheticProcess>(tids); 89 90 return base::OkStatus(); 91 } 92 93 } // namespace perfetto::trace_redaction 94