diff options
author | 2021-03-16 17:22:14 +0000 | |
---|---|---|
committer | 2021-03-17 10:54:56 +0000 | |
commit | d1c8aaedf0eb3982f7e969ab66a2c391dbfd6929 (patch) | |
tree | d6d568b2e92e4f0d7408783e7bb6894bf6bc187b /perfetto_hprof | |
parent | 98fa40a492c85fad5f4f60d2904a1451ee35d543 (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.cc | 11 |
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) { |