xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/proto/profile_packet_utils.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2020 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_PROFILE_PACKET_UTILS_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROFILE_PACKET_UTILS_H_
19 #include <optional>
20 
21 #include "perfetto/ext/base/string_view.h"
22 #include "src/trace_processor/importers/proto/profile_packet_sequence_state.h"
23 
24 #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
25 #include "protos/perfetto/trace/profiling/profile_common.pbzero.h"
26 #include "protos/perfetto/trace/profiling/profile_packet.pbzero.h"
27 
28 namespace perfetto {
29 namespace trace_processor {
30 
31 class ProfilePacketUtils {
32  public:
33   static std::string MakeMappingName(
34       const std::vector<base::StringView>& path_components);
35 
MakeSourceMapping(const protos::pbzero::Mapping::Decoder & entry)36   static ProfilePacketSequenceState::SourceMapping MakeSourceMapping(
37       const protos::pbzero::Mapping::Decoder& entry) {
38     ProfilePacketSequenceState::SourceMapping src_mapping{};
39     src_mapping.build_id = entry.build_id();
40     src_mapping.exact_offset = entry.exact_offset();
41     src_mapping.start_offset = entry.start_offset();
42     src_mapping.start = entry.start();
43     src_mapping.end = entry.end();
44     src_mapping.load_bias = entry.load_bias();
45     for (auto path_string_id_it = entry.path_string_ids(); path_string_id_it;
46          ++path_string_id_it) {
47       src_mapping.name_ids.emplace_back(*path_string_id_it);
48     }
49     return src_mapping;
50   }
51 
MakeSourceFrame(const protos::pbzero::Frame::Decoder & entry)52   static ProfilePacketSequenceState::SourceFrame MakeSourceFrame(
53       const protos::pbzero::Frame::Decoder& entry) {
54     ProfilePacketSequenceState::SourceFrame src_frame;
55     src_frame.name_id = entry.function_name_id();
56     src_frame.mapping_id = entry.mapping_id();
57     src_frame.rel_pc = entry.rel_pc();
58     return src_frame;
59   }
60 
MakeSourceCallstack(const protos::pbzero::Callstack::Decoder & entry)61   static ProfilePacketSequenceState::SourceCallstack MakeSourceCallstack(
62       const protos::pbzero::Callstack::Decoder& entry) {
63     ProfilePacketSequenceState::SourceCallstack src_callstack;
64     for (auto frame_it = entry.frame_ids(); frame_it; ++frame_it)
65       src_callstack.emplace_back(*frame_it);
66     return src_callstack;
67   }
68 
StringifyCpuMode(protos::pbzero::Profiling::CpuMode cpu_mode)69   static const char* StringifyCpuMode(
70       protos::pbzero::Profiling::CpuMode cpu_mode) {
71     using protos::pbzero::Profiling;
72     switch (cpu_mode) {
73       case Profiling::MODE_UNKNOWN:
74         return "unknown";
75       case Profiling::MODE_KERNEL:
76         return "kernel";
77       case Profiling::MODE_USER:
78         return "user";
79       case Profiling::MODE_HYPERVISOR:
80         return "hypervisor";
81       case Profiling::MODE_GUEST_KERNEL:
82         return "guest_kernel";
83       case Profiling::MODE_GUEST_USER:
84         return "guest_user";
85     }
86     return "unknown";  // switch should be complete, but gcc needs a hint
87   }
88 
StringifyStackUnwindError(protos::pbzero::Profiling::StackUnwindError unwind_error)89   static const char* StringifyStackUnwindError(
90       protos::pbzero::Profiling::StackUnwindError unwind_error) {
91     using protos::pbzero::Profiling;
92     switch (unwind_error) {
93       case Profiling::UNWIND_ERROR_UNKNOWN:
94         return "unknown";
95       case Profiling::UNWIND_ERROR_NONE:
96         return "none";  // should never see this serialized by traced_perf, the
97                         // field should be unset instead
98       case Profiling::UNWIND_ERROR_MEMORY_INVALID:
99         return "memory_invalid";
100       case Profiling::UNWIND_ERROR_UNWIND_INFO:
101         return "unwind_info";
102       case Profiling::UNWIND_ERROR_UNSUPPORTED:
103         return "unsupported";
104       case Profiling::UNWIND_ERROR_INVALID_MAP:
105         return "invalid_map";
106       case Profiling::UNWIND_ERROR_MAX_FRAMES_EXCEEDED:
107         return "max_frames_exceeded";
108       case Profiling::UNWIND_ERROR_REPEATED_FRAME:
109         return "repeated_frame";
110       case Profiling::UNWIND_ERROR_INVALID_ELF:
111         return "invalid_elf";
112       case Profiling::UNWIND_ERROR_SYSTEM_CALL:
113         return "system_call";
114       case Profiling::UNWIND_ERROR_THREAD_TIMEOUT:
115         return "thread_timeout";
116       case Profiling::UNWIND_ERROR_THREAD_DOES_NOT_EXIST:
117         return "thread_does_not_exist";
118       case Profiling::UNWIND_ERROR_BAD_ARCH:
119         return "bad_arch";
120       case Profiling::UNWIND_ERROR_MAPS_PARSE:
121         return "maps_parse";
122       case Profiling::UNWIND_ERROR_INVALID_PARAMETER:
123         return "invalid_parameter";
124       case Profiling::UNWIND_ERROR_PTRACE_CALL:
125         return "ptrace_call";
126     }
127     return "unknown";  // switch should be complete, but gcc needs a hint
128   }
129 };
130 
131 }  // namespace trace_processor
132 }  // namespace perfetto
133 
134 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROFILE_PACKET_UTILS_H_
135