summaryrefslogtreecommitdiff
path: root/perfetto_hprof
diff options
context:
space:
mode:
author Florian Mayer <fmayer@google.com> 2021-03-16 17:22:14 +0000
committer Florian Mayer <fmayer@google.com> 2021-03-17 10:54:56 +0000
commitd1c8aaedf0eb3982f7e969ab66a2c391dbfd6929 (patch)
treed6d568b2e92e4f0d7408783e7bb6894bf6bc187b /perfetto_hprof
parent98fa40a492c85fad5f4f60d2904a1451ee35d543 (diff)
perfetto_hprof: Unsuspend parent process before waitpid.
We have hit bugs where the child process got stuck in an atfork handler. This way worst case the perfetto_hprof_listener thread gets stuck if the child process does, but the rest of the app can go on normally. The next step will be to add a timeout to the waitpid to make sure we do not leak the child process. Bug: 181031512 Test: atest CtsPerfettoTestCases Change-Id: I9525c0fc5d061307b01dbacf2ec05f19b930ea25
Diffstat (limited to 'perfetto_hprof')
-rw-r--r--perfetto_hprof/perfetto_hprof.cc11
1 files changed, 8 insertions, 3 deletions
diff --git a/perfetto_hprof/perfetto_hprof.cc b/perfetto_hprof/perfetto_hprof.cc
index ebba1e3e17..8bcf0bd125 100644
--- a/perfetto_hprof/perfetto_hprof.cc
+++ b/perfetto_hprof/perfetto_hprof.cc
@@ -32,6 +32,7 @@
#include <time.h>
#include <limits>
+#include <optional>
#include <type_traits>
#include "gc/heap-visit-objects-inl.h"
@@ -584,10 +585,10 @@ void DumpPerfetto(art::Thread* self) {
// We need to do this before the fork, because otherwise it can deadlock
// waiting for the GC, as all other threads get terminated by the clone, but
// their locks are not released.
- art::gc::ScopedGCCriticalSection gcs(self, art::gc::kGcCauseHprof,
- art::gc::kCollectorTypeHprof);
+ std::optional<art::gc::ScopedGCCriticalSection> gcs(std::in_place, self, art::gc::kGcCauseHprof,
+ art::gc::kCollectorTypeHprof);
- art::ScopedSuspendAll ssa(__FUNCTION__, /* long_suspend=*/ true);
+ std::optional<art::ScopedSuspendAll> ssa(std::in_place, __FUNCTION__, /* long_suspend=*/ true);
pid_t pid = fork();
if (pid == -1) {
@@ -597,6 +598,10 @@ void DumpPerfetto(art::Thread* self) {
}
if (pid != 0) {
// Parent
+ // Stop the thread suspension as soon as possible to allow the rest of the application to
+ // continue while we waitpid here.
+ ssa.reset();
+ gcs.reset();
int stat_loc;
for (;;) {
if (waitpid(pid, &stat_loc, 0) != -1 || errno != EINTR) {