• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   ModuleCacheForTracing* module_cache = static_cast<ModuleCacheForTracing*>(
120       ctx->GetTlsUserData(kModuleCacheForTracingKey));
121   if (!module_cache) {
122     auto new_module_cache = std::make_unique<ModuleCacheForTracing>();
123     module_cache = new_module_cache.get();
124     ctx->SetTlsUserData(kModuleCacheForTracingKey, std::move(new_module_cache));
125   }
126   const base::ModuleCache::Module* module =
127       module_cache->GetModuleCache().GetModuleForAddress(address);
128   if (!module) {
129     return std::nullopt;
130   }
131   size_t iid;
132   if (index_for_field->index_.LookUpOrInsert(&iid, address)) {
133     return iid;
134   }
135   const auto mapping_id = InternedMapping::Get(ctx, module);
136   const uintptr_t rel_pc = address - module->GetBaseAddress();
137   InternedUnsymbolizedSourceLocation::Add(
138       ctx->GetIncrementalState()->serialized_interned_data.get(), iid,
139       base::trace_event::UnsymbolizedSourceLocation(mapping_id, rel_pc));
140   return iid;
141 }
142 
143 // static
Add(perfetto::protos::pbzero::InternedData * interned_data,size_t iid,const UnsymbolizedSourceLocation & location)144 void InternedUnsymbolizedSourceLocation::Add(
145     perfetto::protos::pbzero::InternedData* interned_data,
146     size_t iid,
147     const UnsymbolizedSourceLocation& location) {
148   auto* msg = interned_data->add_unsymbolized_source_locations();
149   msg->set_iid(iid);
150   msg->set_mapping_id(location.mapping_id);
151   msg->set_rel_pc(location.rel_pc);
152 }
153 
154 }  // namespace trace_event
155 }  // namespace base
156