xref: /aosp_15_r20/external/cronet/base/trace_event/interned_args_helper.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/trace_event/interned_args_helper.h"
6 
7 #include "third_party/perfetto/include/perfetto/tracing/track_event_interned_data_index.h"
8 #include "third_party/perfetto/protos/perfetto/trace/interned_data/interned_data.pbzero.h"
9 #include "third_party/perfetto/protos/perfetto/trace/profiling/profile_common.pbzero.h"
10 #include "third_party/perfetto/protos/perfetto/trace/track_event/log_message.pbzero.h"
11 #include "third_party/perfetto/protos/perfetto/trace/track_event/source_location.pbzero.h"
12 #include "third_party/perfetto/protos/perfetto/trace/track_event/task_execution.pbzero.h"
13 
14 namespace base {
15 namespace trace_event {
16 
17 namespace {
18 
19 const void* const kModuleCacheForTracingKey = &kModuleCacheForTracingKey;
20 
21 class ModuleCacheForTracing : public perfetto::TrackEventTlsStateUserData {
22  public:
23   ModuleCacheForTracing() = default;
24   ~ModuleCacheForTracing() override = default;
25 
GetModuleCache()26   base::ModuleCache& GetModuleCache() { return module_cache_; }
27 
28  private:
29   base::ModuleCache module_cache_;
30 };
31 
32 }  // namespace
33 
34 //  static
Add(perfetto::protos::pbzero::InternedData * interned_data,size_t iid,const TraceSourceLocation & location)35 void InternedSourceLocation::Add(
36     perfetto::protos::pbzero::InternedData* interned_data,
37     size_t iid,
38     const TraceSourceLocation& location) {
39   auto* msg = interned_data->add_source_locations();
40   msg->set_iid(iid);
41   if (location.file_name != nullptr)
42     msg->set_file_name(location.file_name);
43   if (location.function_name != nullptr)
44     msg->set_function_name(location.function_name);
45   // TODO(ssid): Add line number once it is allowed in internal proto.
46   // TODO(ssid): Add program counter to the proto fields when
47   // !BUILDFLAG(ENABLE_LOCATION_SOURCE).
48   // TODO(http://crbug.com760702) remove file name and just pass the program
49   // counter to the heap profiler macro.
50   // TODO(ssid): Consider writing the program counter of the current task
51   // (from the callback function pointer) instead of location that posted the
52   // task.
53 }
54 
55 // static
Add(perfetto::protos::pbzero::InternedData * interned_data,size_t iid,const std::string & log_message)56 void InternedLogMessage::Add(
57     perfetto::protos::pbzero::InternedData* interned_data,
58     size_t iid,
59     const std::string& log_message) {
60   auto* msg = interned_data->add_log_message_body();
61   msg->set_iid(iid);
62   msg->set_body(log_message);
63 }
64 
65 // static
Add(perfetto::protos::pbzero::InternedData * interned_data,size_t iid,const std::string & build_id)66 void InternedBuildId::Add(perfetto::protos::pbzero::InternedData* interned_data,
67                           size_t iid,
68                           const std::string& build_id) {
69   auto* msg = interned_data->add_build_ids();
70   msg->set_iid(iid);
71   msg->set_str(build_id);
72 }
73 
74 // static
Add(perfetto::protos::pbzero::InternedData * interned_data,size_t iid,const std::string & mapping_path)75 void InternedMappingPath::Add(
76     perfetto::protos::pbzero::InternedData* interned_data,
77     size_t iid,
78     const std::string& mapping_path) {
79   auto* msg = interned_data->add_mapping_paths();
80   msg->set_iid(iid);
81   msg->set_str(mapping_path);
82 }
83 
84 // static
Get(perfetto::EventContext * ctx,const base::ModuleCache::Module * module)85 size_t InternedMapping::Get(perfetto::EventContext* ctx,
86                             const base::ModuleCache::Module* module) {
87   auto* index_for_field = GetOrCreateIndexForField(ctx->GetIncrementalState());
88   size_t iid;
89   if (index_for_field->index_.LookUpOrInsert(&iid, module)) {
90     return iid;
91   }
92   InternedMapping::Add(ctx, iid, module);
93   return iid;
94 }
95 
96 // static
Add(perfetto::EventContext * ctx,size_t iid,const base::ModuleCache::Module * module)97 void InternedMapping::Add(perfetto::EventContext* ctx,
98                           size_t iid,
99                           const base::ModuleCache::Module* module) {
100   // TODO(b/270470700): Remove TransformModuleIDToSymbolServerFormat on all
101   // platforms once tools/tracing is fixed.
102   const auto build_id = InternedBuildId::Get(
103       ctx, base::TransformModuleIDToSymbolServerFormat(module->GetId()));
104   const auto path_id =
105       InternedMappingPath::Get(ctx, module->GetDebugBasename().MaybeAsASCII());
106 
107   auto* msg =
108       ctx->GetIncrementalState()->serialized_interned_data->add_mappings();
109   msg->set_iid(iid);
110   msg->set_build_id(build_id);
111   msg->add_path_string_ids(path_id);
112 }
113 
114 // static
Get(perfetto::EventContext * ctx,uintptr_t address)115 std::optional<size_t> InternedUnsymbolizedSourceLocation::Get(
116     perfetto::EventContext* ctx,
117     uintptr_t address) {
118   auto* index_for_field = GetOrCreateIndexForField(ctx->GetIncrementalState());
119 #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
120   ModuleCacheForTracing* module_cache = static_cast<ModuleCacheForTracing*>(
121       ctx->GetTlsUserData(kModuleCacheForTracingKey));
122   if (!module_cache) {
123     auto new_module_cache = std::make_unique<ModuleCacheForTracing>();
124     module_cache = new_module_cache.get();
125     ctx->SetTlsUserData(kModuleCacheForTracingKey, std::move(new_module_cache));
126   }
127   const base::ModuleCache::Module* module =
128       module_cache->GetModuleCache().GetModuleForAddress(address);
129 #else
130   const base::ModuleCache::Module* module =
131       index_for_field->module_cache_.GetModuleForAddress(address);
132 #endif
133   if (!module) {
134     return std::nullopt;
135   }
136   size_t iid;
137   if (index_for_field->index_.LookUpOrInsert(&iid, address)) {
138     return iid;
139   }
140   const auto mapping_id = InternedMapping::Get(ctx, module);
141   const uintptr_t rel_pc = address - module->GetBaseAddress();
142   InternedUnsymbolizedSourceLocation::Add(
143       ctx->GetIncrementalState()->serialized_interned_data.get(), iid,
144       base::trace_event::UnsymbolizedSourceLocation(mapping_id, rel_pc));
145   return iid;
146 }
147 
148 // static
Add(perfetto::protos::pbzero::InternedData * interned_data,size_t iid,const UnsymbolizedSourceLocation & location)149 void InternedUnsymbolizedSourceLocation::Add(
150     perfetto::protos::pbzero::InternedData* interned_data,
151     size_t iid,
152     const UnsymbolizedSourceLocation& location) {
153   auto* msg = interned_data->add_unsymbolized_source_locations();
154   msg->set_iid(iid);
155   msg->set_mapping_id(location.mapping_id);
156   msg->set_rel_pc(location.rel_pc);
157 }
158 
159 }  // namespace trace_event
160 }  // namespace base
161