xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/perf/perf_session.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PERF_PERF_SESSION_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_PERF_PERF_SESSION_H_
19 
20 #include <sys/types.h>
21 #include <cstddef>
22 #include <cstdint>
23 #include <optional>
24 #include <string>
25 #include <utility>
26 #include <vector>
27 
28 #include "perfetto/ext/base/flat_hash_map.h"
29 #include "perfetto/ext/base/hash.h"
30 #include "perfetto/ext/base/status_or.h"
31 #include "perfetto/trace_processor/ref_counted.h"
32 #include "perfetto/trace_processor/trace_blob_view.h"
33 #include "src/trace_processor/importers/perf/perf_event.h"
34 #include "src/trace_processor/importers/perf/perf_event_attr.h"
35 #include "src/trace_processor/tables/profiler_tables_py.h"
36 #include "src/trace_processor/util/build_id.h"
37 
38 namespace perfetto::trace_processor {
39 
40 class TraceProcessorContext;
41 
42 namespace perf_importer {
43 
44 // Helper to deal with perf_event_attr instances in a perf file.
45 class PerfSession : public RefCounted {
46  public:
47   class Builder {
48    public:
Builder(TraceProcessorContext * context)49     explicit Builder(TraceProcessorContext* context) : context_(context) {}
50     base::StatusOr<RefPtr<PerfSession>> Build();
AddAttrAndIds(perf_event_attr attr,std::vector<uint64_t> ids)51     Builder& AddAttrAndIds(perf_event_attr attr, std::vector<uint64_t> ids) {
52       attr_with_ids_.push_back({attr, std::move(ids)});
53       return *this;
54     }
55 
56    private:
57     struct PerfEventAttrWithIds {
58       perf_event_attr attr;
59       std::vector<uint64_t> ids;
60     };
61     TraceProcessorContext* const context_;
62     std::vector<PerfEventAttrWithIds> attr_with_ids_;
63   };
64 
perf_session_id()65   tables::PerfSessionTable::Id perf_session_id() const {
66     return perf_session_id_;
67   }
68 
69   RefPtr<PerfEventAttr> FindAttrForEventId(uint64_t id) const;
70 
71   base::StatusOr<RefPtr<PerfEventAttr>> FindAttrForRecord(
72       const perf_event_header& header,
73       const TraceBlobView& payload) const;
74 
75   void SetCmdline(const std::vector<std::string>& args);
76   void SetEventName(uint64_t event_id, std::string name);
77   void SetEventName(uint32_t type, uint64_t config, const std::string& name);
78 
79   void AddBuildId(int32_t pid, std::string filename, BuildId build_id);
80   std::optional<BuildId> LookupBuildId(uint32_t pid,
81                                        const std::string& filename) const;
82 
83   // The kernel stores the return address for non leaf frames in call chains.
84   // Simpleperf accounts for this when writing perf data files, linux perf does
85   // not. This method returns true if we need to convert return addresses to
86   // call sites when parsing call chains (i.e. if the trace comes from linux
87   // perf).
needs_pc_adjustment()88   bool needs_pc_adjustment() const { return is_simpleperf_ == false; }
89 
SetIsSimpleperf()90   void SetIsSimpleperf() { is_simpleperf_ = true; }
91 
92   bool HasPerfClock() const;
93 
94  private:
95   struct BuildIdMapKey {
96     int32_t pid;
97     std::string filename;
98 
99     struct Hasher {
operatorBuildIdMapKey::Hasher100       size_t operator()(const BuildIdMapKey& k) const {
101         return static_cast<size_t>(base::Hasher::Combine(k.pid, k.filename));
102       }
103     };
104 
105     bool operator==(const BuildIdMapKey& o) const {
106       return pid == o.pid && filename == o.filename;
107     }
108   };
109 
PerfSession(TraceProcessorContext * context,tables::PerfSessionTable::Id perf_session_id,RefPtr<PerfEventAttr> first_attr,base::FlatHashMap<uint64_t,RefPtr<PerfEventAttr>> attrs_by_id,bool has_single_perf_event_attr)110   PerfSession(TraceProcessorContext* context,
111               tables::PerfSessionTable::Id perf_session_id,
112               RefPtr<PerfEventAttr> first_attr,
113               base::FlatHashMap<uint64_t, RefPtr<PerfEventAttr>> attrs_by_id,
114               bool has_single_perf_event_attr)
115       : context_(context),
116         perf_session_id_(perf_session_id),
117         first_attr_(std::move(first_attr)),
118         attrs_by_id_(std::move(attrs_by_id)),
119         has_single_perf_event_attr_(has_single_perf_event_attr) {}
120 
121   bool ReadEventId(const perf_event_header& header,
122                    const TraceBlobView& payload,
123                    uint64_t& id) const;
124 
125   TraceProcessorContext* const context_;
126   tables::PerfSessionTable::Id perf_session_id_;
127   RefPtr<PerfEventAttr> first_attr_;
128   base::FlatHashMap<uint64_t, RefPtr<PerfEventAttr>> attrs_by_id_;
129 
130   // Multiple ids can map to the same perf_event_attr. This member tells us
131   // whether there was only one perf_event_attr (with potentially different ids
132   // associated). This makes the attr lookup given a record trivial and not
133   // dependant no having any id field in the records.
134   bool has_single_perf_event_attr_;
135 
136   bool is_simpleperf_ = false;
137 
138   base::FlatHashMap<BuildIdMapKey, BuildId, BuildIdMapKey::Hasher> build_ids_;
139 };
140 
141 }  // namespace perf_importer
142 }  // namespace perfetto::trace_processor
143 
144 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_PERF_PERF_SESSION_H_
145