Allow to use PERFETTO_BINARY_PATH in trace_processor_shell.

Test: PERFETTO_BINARY_PATH=... out/r/trace_processor_shell trace
      look at stack_profile_symbol
Bug: 146479871
Change-Id: Ib8ef09a08183ec8762570cd5ea8148f729d1cb40
diff --git a/Android.bp b/Android.bp
index d18eb82..8144ef3 100644
--- a/Android.bp
+++ b/Android.bp
@@ -6822,6 +6822,8 @@
     ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
     ":perfetto_protos_perfetto_trace_track_event_zero_gen",
     ":perfetto_src_base_base",
+    ":perfetto_src_profiling_symbolizer_symbolize_database",
+    ":perfetto_src_profiling_symbolizer_symbolizer",
     ":perfetto_src_protozero_protozero",
     ":perfetto_src_trace_processor_containers_containers",
     ":perfetto_src_trace_processor_db_lib",
diff --git a/BUILD b/BUILD
index ae16edc..cd61821 100644
--- a/BUILD
+++ b/BUILD
@@ -2597,6 +2597,8 @@
         ":include_perfetto_trace_processor_trace_processor",
         ":src_base_base",
         ":src_base_unix_socket",
+        ":src_profiling_symbolizer_symbolize_database",
+        ":src_profiling_symbolizer_symbolizer",
         ":src_protozero_protozero",
         ":src_trace_processor_containers_containers",
         ":src_trace_processor_db_lib",
diff --git a/src/profiling/symbolizer/symbolize_database.cc b/src/profiling/symbolizer/symbolize_database.cc
index 39e09a4..23ab640 100644
--- a/src/profiling/symbolizer/symbolize_database.cc
+++ b/src/profiling/symbolizer/symbolize_database.cc
@@ -21,11 +21,13 @@
 #include <vector>
 
 #include "perfetto/base/logging.h"
+#include "perfetto/ext/base/string_splitter.h"
 
 #include "perfetto/protozero/scattered_heap_buffer.h"
 #include "perfetto/trace_processor/trace_processor.h"
 
 #include "protos/perfetto/trace/profiling/profile_common.pbzero.h"
+#include "protos/perfetto/trace/trace.pbzero.h"
 #include "protos/perfetto/trace/trace_packet.pbzero.h"
 
 namespace perfetto {
@@ -101,7 +103,8 @@
     if (res.empty())
       continue;
 
-    protozero::HeapBuffered<perfetto::protos::pbzero::TracePacket> packet;
+    protozero::HeapBuffered<perfetto::protos::pbzero::Trace> trace;
+    auto* packet = trace->add_packet();
     auto* module_symbols = packet->set_module_symbols();
     module_symbols->set_path(name_and_buildid.first);
     module_symbols->set_build_id(name_and_buildid.second);
@@ -116,9 +119,19 @@
         line->set_line_number(frame.line);
       }
     }
-    callback(packet.SerializeAsString());
+    callback(trace.SerializeAsString());
   }
 }
 
+std::vector<std::string> GetPerfettoBinaryPath() {
+  std::vector<std::string> roots;
+  const char* root = getenv("PERFETTO_BINARY_PATH");
+  if (root != nullptr) {
+    for (base::StringSplitter sp(std::string(root), ':'); sp.Next();)
+      roots.emplace_back(sp.cur_token(), sp.cur_token_size());
+  }
+  return roots;
+}
+
 }  // namespace profiling
 }  // namespace perfetto
diff --git a/src/profiling/symbolizer/symbolize_database.h b/src/profiling/symbolizer/symbolize_database.h
index 6c9ab1b..ee9cfc1 100644
--- a/src/profiling/symbolizer/symbolize_database.h
+++ b/src/profiling/symbolizer/symbolize_database.h
@@ -21,12 +21,14 @@
 
 #include <functional>
 #include <string>
+#include <vector>
 
 namespace perfetto {
 namespace trace_processor {
 class TraceProcessor;
 }
 namespace profiling {
+std::vector<std::string> GetPerfettoBinaryPath();
 // Generate ModuleSymbol protos for all unsymbolized frames in the database.
 // Wrap them in proto-encoded TracePackets messages and call callback.
 void SymbolizeDatabase(trace_processor::TraceProcessor* tp,
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 4cf226e..e2a559d 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -379,6 +379,8 @@
       ":lib",
       "../../gn:default_deps",
       "../../gn:protoc_lib",
+      "../../src/profiling/symbolizer",
+      "../../src/profiling/symbolizer:symbolize_database",
       "../base",
       "metrics:lib",
     ]
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index 54855c5..5cc06cb 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -43,6 +43,13 @@
 #include "src/trace_processor/rpc/httpd.h"
 #endif
 
+#include "src/profiling/symbolizer/symbolize_database.h"
+#include "src/profiling/symbolizer/symbolizer.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_LOCAL_SYMBOLIZER)
+#include "src/profiling/symbolizer/local_symbolizer.h"
+#endif
+
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
     PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
@@ -913,6 +920,31 @@
                     options.trace_file_path.c_str(), read_status.c_message());
       return 1;
     }
+
+    std::unique_ptr<profiling::Symbolizer> symbolizer;
+    auto binary_path = profiling::GetPerfettoBinaryPath();
+    if (!binary_path.empty()) {
+#if PERFETTO_BUILDFLAG(PERFETTO_LOCAL_SYMBOLIZER)
+      symbolizer.reset(new profiling::LocalSymbolizer(std::move(binary_path)));
+#else
+      PERFETTO_FATAL("This build does not support local symbolization.");
+#endif
+    }
+    if (symbolizer) {
+      profiling::SymbolizeDatabase(
+          tp.get(), symbolizer.get(), [&tp](const std::string& trace_proto) {
+            std::unique_ptr<uint8_t[]> buf(new uint8_t[trace_proto.size()]);
+            memcpy(buf.get(), trace_proto.data(), trace_proto.size());
+            auto status = tp->Parse(std::move(buf), trace_proto.size());
+            if (!status.ok()) {
+              PERFETTO_DFATAL_OR_ELOG("Failed to parse: %s",
+                                      status.message().c_str());
+              return;
+            }
+          });
+      tp->NotifyEndOfFile();
+    }
+
     t_load = base::GetWallTimeNs() - t_load_start;
     double t_load_s = t_load.count() / 1E9;
     PERFETTO_ILOG("Trace loaded: %.2f MB (%.1f MB/s)", size_mb,
diff --git a/tools/trace_to_text/pprof_builder.cc b/tools/trace_to_text/pprof_builder.cc
index 1b1014d..4da0d9d 100644
--- a/tools/trace_to_text/pprof_builder.cc
+++ b/tools/trace_to_text/pprof_builder.cc
@@ -520,16 +520,10 @@
                   const std::vector<uint64_t>& timestamps) {
   if (symbolizer) {
     profiling::SymbolizeDatabase(
-        tp, symbolizer, [&tp](const std::string& packet_proto) {
-          std::unique_ptr<uint8_t[]> buf(new uint8_t[11 + packet_proto.size()]);
-          uint8_t* wptr = &buf[0];
-          *(wptr++) =
-              MakeTagLengthDelimited(protos::pbzero::Trace::kPacketFieldNumber);
-          wptr = WriteVarInt(packet_proto.size(), wptr);
-          memcpy(wptr, packet_proto.data(), packet_proto.size());
-          wptr += packet_proto.size();
-          size_t buf_size = static_cast<size_t>(wptr - &buf[0]);
-          auto status = tp->Parse(std::move(buf), buf_size);
+        tp, symbolizer, [tp](const std::string& trace_proto) {
+          std::unique_ptr<uint8_t[]> buf(new uint8_t[trace_proto.size()]);
+          memcpy(buf.get(), trace_proto.data(), trace_proto.size());
+          auto status = tp->Parse(std::move(buf), trace_proto.size());
           if (!status.ok()) {
             PERFETTO_DFATAL_OR_ELOG("Failed to parse: %s",
                                     status.message().c_str());
diff --git a/tools/trace_to_text/symbolize_profile.cc b/tools/trace_to_text/symbolize_profile.cc
index 7cf1e10..acf25f0 100644
--- a/tools/trace_to_text/symbolize_profile.cc
+++ b/tools/trace_to_text/symbolize_profile.cc
@@ -39,10 +39,10 @@
 // be prepended to the profile to attach the symbol information.
 int SymbolizeProfile(std::istream* input, std::ostream* output) {
   std::unique_ptr<profiling::Symbolizer> symbolizer;
-  auto binary_path = GetPerfettoBinaryPath();
+  auto binary_path = profiling::GetPerfettoBinaryPath();
   if (!binary_path.empty()) {
 #if PERFETTO_BUILDFLAG(PERFETTO_LOCAL_SYMBOLIZER)
-    symbolizer.reset(new profiling::LocalSymbolizer(GetPerfettoBinaryPath()));
+    symbolizer.reset(new profiling::LocalSymbolizer(std::move(binary_path)));
 #else
     PERFETTO_FATAL("This build does not support local symbolization.");
 #endif
@@ -59,10 +59,9 @@
 
   tp->NotifyEndOfFile();
 
-  SymbolizeDatabase(tp.get(), symbolizer.get(),
-                    [output](const std::string& packet_proto) {
-                      WriteTracePacket(packet_proto, output);
-                    });
+  SymbolizeDatabase(
+      tp.get(), symbolizer.get(),
+      [output](const std::string& trace_proto) { *output << trace_proto; });
   return 0;
 }
 
diff --git a/tools/trace_to_text/trace_to_profile.cc b/tools/trace_to_text/trace_to_profile.cc
index ae9a2a5..1d3846c 100644
--- a/tools/trace_to_text/trace_to_profile.cc
+++ b/tools/trace_to_text/trace_to_profile.cc
@@ -21,6 +21,7 @@
 
 #include "perfetto/base/build_config.h"
 
+#include "src/profiling/symbolizer/symbolize_database.h"
 #if PERFETTO_BUILDFLAG(PERFETTO_LOCAL_SYMBOLIZER)
 #include "src/profiling/symbolizer/local_symbolizer.h"
 #endif
@@ -54,10 +55,10 @@
                    uint64_t pid,
                    std::vector<uint64_t> timestamps) {
   std::unique_ptr<profiling::Symbolizer> symbolizer;
-  auto binary_path = GetPerfettoBinaryPath();
+  auto binary_path = profiling::GetPerfettoBinaryPath();
   if (!binary_path.empty()) {
 #if PERFETTO_BUILDFLAG(PERFETTO_LOCAL_SYMBOLIZER)
-    symbolizer.reset(new profiling::LocalSymbolizer(GetPerfettoBinaryPath()));
+    symbolizer.reset(new profiling::LocalSymbolizer(std::move(binary_path)));
 #else
     PERFETTO_ELOG(
         "This build does not support local symbolization. "
diff --git a/tools/trace_to_text/utils.cc b/tools/trace_to_text/utils.cc
index efc05f5..73645f6 100644
--- a/tools/trace_to_text/utils.cc
+++ b/tools/trace_to_text/utils.cc
@@ -25,7 +25,6 @@
 #include <utility>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/protozero/scattered_heap_buffer.h"
 #include "perfetto/trace_processor/trace_processor.h"
 
@@ -133,16 +132,6 @@
   }
 }
 
-std::vector<std::string> GetPerfettoBinaryPath() {
-  std::vector<std::string> roots;
-  const char* root = getenv("PERFETTO_BINARY_PATH");
-  if (root != nullptr) {
-    for (base::StringSplitter sp(std::string(root), ':'); sp.Next();)
-      roots.emplace_back(sp.cur_token(), sp.cur_token_size());
-  }
-  return roots;
-}
-
 base::Optional<std::string> GetPerfettoProguardMapPath() {
   base::Optional<std::string> proguard_map;
   const char* env = getenv("PERFETTO_PROGUARD_MAP");
diff --git a/tools/trace_to_text/utils.h b/tools/trace_to_text/utils.h
index 46c86f9..19bd3ca 100644
--- a/tools/trace_to_text/utils.h
+++ b/tools/trace_to_text/utils.h
@@ -57,7 +57,6 @@
     std::istream* input,
     const std::function<void(std::unique_ptr<char[]>, size_t)>&);
 
-std::vector<std::string> GetPerfettoBinaryPath();
 base::Optional<std::string> GetPerfettoProguardMapPath();
 
 bool ReadTrace(trace_processor::TraceProcessor* tp, std::istream* input);