heapprofd: split main() in a seprate target

This splits the main() symbol from HeapprofdMain()
so the latter can be referred by other executables.
This is consistent with what we did with the other
daemons. #fixit

Bug: 187945217
Change-Id: Iee2f406703d44330bbe57ff0e95550d50b4783a5
diff --git a/Android.bp b/Android.bp
index de0d6e9..1d83399 100644
--- a/Android.bp
+++ b/Android.bp
@@ -83,6 +83,7 @@
     ":perfetto_src_profiling_common_profiler_guardrails",
     ":perfetto_src_profiling_common_unwind_support",
     ":perfetto_src_profiling_memory_daemon",
+    ":perfetto_src_profiling_memory_heapprofd_main",
     ":perfetto_src_profiling_memory_ring_buffer",
     ":perfetto_src_profiling_memory_scoped_spinlock",
     ":perfetto_src_profiling_memory_wire_protocol",
@@ -7287,6 +7288,14 @@
   ],
 }
 
+// GN: //src/profiling/memory:heapprofd_main
+filegroup {
+  name: "perfetto_src_profiling_memory_heapprofd_main",
+  srcs: [
+    "src/profiling/memory/heapprofd.cc",
+  ],
+}
+
 // GN: //src/profiling/memory:malloc_interceptor_bionic_hooks
 filegroup {
   name: "perfetto_src_profiling_memory_malloc_interceptor_bionic_hooks",
diff --git a/gn/BUILD.gn b/gn/BUILD.gn
index 1f799ad..7fc0cdd 100644
--- a/gn/BUILD.gn
+++ b/gn/BUILD.gn
@@ -79,6 +79,8 @@
     "PERFETTO_TP_JSON=$enable_perfetto_trace_processor_json",
     "PERFETTO_LOCAL_SYMBOLIZER=$perfetto_local_symbolizer",
     "PERFETTO_ZLIB=$enable_perfetto_zlib",
+    "PERFETTO_TRACED_PERF=$enable_perfetto_traced_perf",
+    "PERFETTO_HEAPPROFD=$enable_perfetto_heapprofd",
   ]
 
   rel_out_path = rebase_path(gen_header_path, "$root_build_dir")
diff --git a/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h b/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
index f0179c6..d68f557 100644
--- a/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
+++ b/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
@@ -38,6 +38,8 @@
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_JSON() (0)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LOCAL_SYMBOLIZER() (PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() || PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() ||PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN())
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ZLIB() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TRACED_PERF() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_HEAPPROFD() (1)
 
 // clang-format on
 #endif  // GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
diff --git a/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h b/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
index 6745b3f..dad653c 100644
--- a/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
+++ b/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
@@ -38,6 +38,8 @@
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_JSON() (1)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LOCAL_SYMBOLIZER() (PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() || PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() ||PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN())
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ZLIB() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TRACED_PERF() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_HEAPPROFD() (0)
 
 // clang-format on
 #endif  // GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
diff --git a/src/profiling/memory/BUILD.gn b/src/profiling/memory/BUILD.gn
index f0e350f..804f70e 100644
--- a/src/profiling/memory/BUILD.gn
+++ b/src/profiling/memory/BUILD.gn
@@ -21,6 +21,14 @@
 # The Android heap profiling daemon.
 executable("heapprofd") {
   deps = [
+    ":heapprofd_main",
+    "../../../gn:default_deps",
+  ]
+  sources = [ "main.cc" ]
+}
+
+source_set("heapprofd_main") {
+  deps = [
     "../../../gn:default_deps",
     "../../../protos/perfetto/trace:zero",
     "../../../src/base",
@@ -29,7 +37,10 @@
     "../../../src/profiling/memory:wire_protocol",
     "../../../src/tracing/ipc/producer",
   ]
-  sources = [ "main.cc" ]
+  sources = [
+    "heapprofd.cc",
+    "heapprofd.h",
+  ]
 }
 
 # This library gets loaded into (and executes in) arbitrary android processes.
diff --git a/src/profiling/memory/heapprofd.cc b/src/profiling/memory/heapprofd.cc
new file mode 100644
index 0000000..d3a8cae
--- /dev/null
+++ b/src/profiling/memory/heapprofd.cc
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/profiling/memory/heapprofd.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <array>
+#include <memory>
+#include <vector>
+
+#include <signal.h>
+
+#include "perfetto/ext/base/event_fd.h"
+#include "perfetto/ext/base/getopt.h"
+#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/unix_socket.h"
+#include "perfetto/ext/base/watchdog.h"
+#include "perfetto/ext/tracing/ipc/default_socket.h"
+#include "src/profiling/memory/heapprofd_producer.h"
+#include "src/profiling/memory/java_hprof_producer.h"
+#include "src/profiling/memory/wire_protocol.h"
+
+#include "perfetto/ext/base/unix_task_runner.h"
+
+// TODO(rsavitski): the task runner watchdog spawns a thread (normally for
+// tracking cpu/mem usage) that we don't strictly need.
+
+namespace perfetto {
+namespace profiling {
+namespace {
+
+int StartCentralHeapprofd();
+
+int GetListeningSocket() {
+  const char* sock_fd = getenv(kHeapprofdSocketEnvVar);
+  if (sock_fd == nullptr)
+    PERFETTO_FATAL("Did not inherit socket from init.");
+  char* end;
+  int raw_fd = static_cast<int>(strtol(sock_fd, &end, 10));
+  if (*end != '\0')
+    PERFETTO_FATAL("Invalid %s. Expected decimal integer.",
+                   kHeapprofdSocketEnvVar);
+  return raw_fd;
+}
+
+base::EventFd* g_dump_evt = nullptr;
+
+int StartCentralHeapprofd() {
+  // We set this up before launching any threads, so we do not have to use a
+  // std::atomic for g_dump_evt.
+  g_dump_evt = new base::EventFd();
+
+  base::UnixTaskRunner task_runner;
+  base::Watchdog::GetInstance()->Start();  // crash on exceedingly long tasks
+  HeapprofdProducer producer(HeapprofdMode::kCentral, &task_runner,
+                             /* exit_when_done= */ false);
+
+  int listening_raw_socket = GetListeningSocket();
+  auto listening_socket = base::UnixSocket::Listen(
+      base::ScopedFile(listening_raw_socket), &producer.socket_delegate(),
+      &task_runner, base::SockFamily::kUnix, base::SockType::kStream);
+
+  struct sigaction action = {};
+  action.sa_handler = [](int) { g_dump_evt->Notify(); };
+  // Allow to trigger a full dump by sending SIGUSR1 to heapprofd.
+  // This will allow manually deciding when to dump on userdebug.
+  PERFETTO_CHECK(sigaction(SIGUSR1, &action, nullptr) == 0);
+  task_runner.AddFileDescriptorWatch(g_dump_evt->fd(), [&producer] {
+    g_dump_evt->Clear();
+    producer.DumpAll();
+  });
+  producer.ConnectWithRetries(GetProducerSocket());
+  // TODO(fmayer): Create one producer that manages both heapprofd and Java
+  // producers, so we do not have two connections to traced.
+  JavaHprofProducer java_producer(&task_runner);
+  java_producer.ConnectWithRetries(GetProducerSocket());
+  task_runner.Run();
+  return 0;
+}
+
+}  // namespace
+
+int HeapprofdMain(int argc, char** argv) {
+  bool cleanup_crash = false;
+
+  enum { kCleanupCrash = 256, kTargetPid, kTargetCmd, kInheritFd };
+  static option long_options[] = {
+      {"cleanup-after-crash", no_argument, nullptr, kCleanupCrash},
+      {nullptr, 0, nullptr, 0}};
+  int c;
+  while ((c = getopt_long(argc, argv, "", long_options, nullptr)) != -1) {
+    switch (c) {
+      case kCleanupCrash:
+        cleanup_crash = true;
+        break;
+    }
+  }
+
+  if (cleanup_crash) {
+    PERFETTO_LOG(
+        "Recovering from crash: unsetting heapprofd system properties. "
+        "Expect SELinux denials for unrelated properties.");
+    SystemProperties::ResetHeapprofdProperties();
+    PERFETTO_LOG(
+        "Finished unsetting heapprofd system properties. "
+        "SELinux denials about properties are unexpected after "
+        "this point.");
+    return 0;
+  }
+
+  // start as a central daemon.
+  return StartCentralHeapprofd();
+}
+
+}  // namespace profiling
+}  // namespace perfetto
diff --git a/src/profiling/memory/heapprofd.h b/src/profiling/memory/heapprofd.h
new file mode 100644
index 0000000..e405585
--- /dev/null
+++ b/src/profiling/memory/heapprofd.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_PROFILING_MEMORY_HEAPPROFD_H_
+#define SRC_PROFILING_MEMORY_HEAPPROFD_H_
+
+namespace perfetto {
+namespace profiling {
+
+int HeapprofdMain(int argc, char** argv);
+
+}  // namespace profiling
+}  // namespace perfetto
+
+#endif  // SRC_PROFILING_MEMORY_HEAPPROFD_H_
diff --git a/src/profiling/memory/main.cc b/src/profiling/memory/main.cc
index f0bb47b..078ca86 100644
--- a/src/profiling/memory/main.cc
+++ b/src/profiling/memory/main.cc
@@ -14,117 +14,7 @@
  * limitations under the License.
  */
 
-#include <stdlib.h>
-#include <unistd.h>
-#include <array>
-#include <memory>
-#include <vector>
-
-#include <signal.h>
-
-#include "perfetto/ext/base/event_fd.h"
-#include "perfetto/ext/base/getopt.h"
-#include "perfetto/ext/base/scoped_file.h"
-#include "perfetto/ext/base/unix_socket.h"
-#include "perfetto/ext/base/watchdog.h"
-#include "perfetto/ext/tracing/ipc/default_socket.h"
-#include "src/profiling/memory/heapprofd_producer.h"
-#include "src/profiling/memory/java_hprof_producer.h"
-#include "src/profiling/memory/wire_protocol.h"
-
-#include "perfetto/ext/base/unix_task_runner.h"
-
-// TODO(rsavitski): the task runner watchdog spawns a thread (normally for
-// tracking cpu/mem usage) that we don't strictly need.
-
-namespace perfetto {
-namespace profiling {
-namespace {
-
-int StartCentralHeapprofd();
-
-int GetListeningSocket() {
-  const char* sock_fd = getenv(kHeapprofdSocketEnvVar);
-  if (sock_fd == nullptr)
-    PERFETTO_FATAL("Did not inherit socket from init.");
-  char* end;
-  int raw_fd = static_cast<int>(strtol(sock_fd, &end, 10));
-  if (*end != '\0')
-    PERFETTO_FATAL("Invalid %s. Expected decimal integer.",
-                   kHeapprofdSocketEnvVar);
-  return raw_fd;
-}
-
-base::EventFd* g_dump_evt = nullptr;
-
-int HeapprofdMain(int argc, char** argv) {
-  bool cleanup_crash = false;
-
-  enum { kCleanupCrash = 256, kTargetPid, kTargetCmd, kInheritFd };
-  static option long_options[] = {
-      {"cleanup-after-crash", no_argument, nullptr, kCleanupCrash},
-      {nullptr, 0, nullptr, 0}};
-  int c;
-  while ((c = getopt_long(argc, argv, "", long_options, nullptr)) != -1) {
-    switch (c) {
-      case kCleanupCrash:
-        cleanup_crash = true;
-        break;
-    }
-  }
-
-  if (cleanup_crash) {
-    PERFETTO_LOG(
-        "Recovering from crash: unsetting heapprofd system properties. "
-        "Expect SELinux denials for unrelated properties.");
-    SystemProperties::ResetHeapprofdProperties();
-    PERFETTO_LOG(
-        "Finished unsetting heapprofd system properties. "
-        "SELinux denials about properties are unexpected after "
-        "this point.");
-    return 0;
-  }
-
-  // start as a central daemon.
-  return StartCentralHeapprofd();
-}
-
-int StartCentralHeapprofd() {
-  // We set this up before launching any threads, so we do not have to use a
-  // std::atomic for g_dump_evt.
-  g_dump_evt = new base::EventFd();
-
-  base::UnixTaskRunner task_runner;
-  base::Watchdog::GetInstance()->Start();  // crash on exceedingly long tasks
-  HeapprofdProducer producer(HeapprofdMode::kCentral, &task_runner,
-                             /* exit_when_done= */ false);
-
-  int listening_raw_socket = GetListeningSocket();
-  auto listening_socket = base::UnixSocket::Listen(
-      base::ScopedFile(listening_raw_socket), &producer.socket_delegate(),
-      &task_runner, base::SockFamily::kUnix, base::SockType::kStream);
-
-  struct sigaction action = {};
-  action.sa_handler = [](int) { g_dump_evt->Notify(); };
-  // Allow to trigger a full dump by sending SIGUSR1 to heapprofd.
-  // This will allow manually deciding when to dump on userdebug.
-  PERFETTO_CHECK(sigaction(SIGUSR1, &action, nullptr) == 0);
-  task_runner.AddFileDescriptorWatch(g_dump_evt->fd(), [&producer] {
-    g_dump_evt->Clear();
-    producer.DumpAll();
-  });
-  producer.ConnectWithRetries(GetProducerSocket());
-  // TODO(fmayer): Create one producer that manages both heapprofd and Java
-  // producers, so we do not have two connections to traced.
-  JavaHprofProducer java_producer(&task_runner);
-  java_producer.ConnectWithRetries(GetProducerSocket());
-  task_runner.Run();
-  return 0;
-}
-
-}  // namespace
-}  // namespace profiling
-}  // namespace perfetto
+#include "src/profiling/memory/heapprofd.h"
 
 int main(int argc, char** argv) {
   return perfetto::profiling::HeapprofdMain(argc, argv);
diff --git a/tools/gen_bazel b/tools/gen_bazel
index f4e3650..a8b7309 100755
--- a/tools/gen_bazel
+++ b/tools/gen_bazel
@@ -43,6 +43,8 @@
     'enable_perfetto_watchdog=true',
     'monolithic_binaries=true',
     'target_os="linux"',
+    'enable_perfetto_heapprofd=false',
+    'enable_perfetto_traced_perf=false',
 ])
 
 # Default targets to translate to the blueprint file.