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.