diff options
-rw-r--r-- | dalvikvm/dalvikvm.cc | 6 | ||||
-rw-r--r-- | dex2oat/dex2oat.cc | 4 | ||||
-rw-r--r-- | openjdkjvm/OpenjdkJvm.cc | 7 | ||||
-rw-r--r-- | perfetto_hprof/perfetto_hprof.cc | 7 | ||||
-rw-r--r-- | runtime/runtime_options.def | 8 |
5 files changed, 22 insertions, 10 deletions
diff --git a/dalvikvm/dalvikvm.cc b/dalvikvm/dalvikvm.cc index 4808a1fa09..f2cc225e8b 100644 --- a/dalvikvm/dalvikvm.cc +++ b/dalvikvm/dalvikvm.cc @@ -215,6 +215,8 @@ extern "C" const char *__asan_default_options() { int main(int argc, char** argv) { // Do not allow static destructors to be called, since it's conceivable that - // daemons may still awaken (literally). - _exit(art::dalvikvm(argc, argv)); + // daemons may still awaken (literally); but still have functions registered + // with `at_quick_exit` (for instance LLVM's code coverage profile dumping + // routine) be called before exiting. + quick_exit(art::dalvikvm(argc, argv)); } diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 9de5ac5704..042d6717eb 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -3134,9 +3134,11 @@ int main(int argc, char** argv) { int result = static_cast<int>(art::Dex2oat(argc, argv)); // Everything was done, do an explicit exit here to avoid running Runtime destructors that take // time (bug 10645725) unless we're a debug or instrumented build or running on a memory tool. + // Also have functions registered with `at_quick_exit` (for instance LLVM's code coverage + // profile dumping routine) be called before exiting. // Note: The Dex2Oat class should not destruct the runtime in this case. if (!art::kIsDebugBuild && !art::kIsPGOInstrumentation && !art::kRunningOnMemoryTool) { - _exit(result); + quick_exit(result); } return result; } diff --git a/openjdkjvm/OpenjdkJvm.cc b/openjdkjvm/OpenjdkJvm.cc index 675a401bb6..18078abdad 100644 --- a/openjdkjvm/OpenjdkJvm.cc +++ b/openjdkjvm/OpenjdkJvm.cc @@ -35,6 +35,7 @@ #include <dlfcn.h> #include <limits.h> #include <stdio.h> +#include <stdlib.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <sys/time.h> @@ -314,8 +315,10 @@ JNIEXPORT __attribute__((noreturn)) void JVM_Exit(jint status) { LOG(INFO) << "System.exit called, status: " << status; art::Runtime::Current()->CallExitHook(status); // Unsafe to call exit() while threads may still be running. They would race - // with static destructors. - _exit(status); + // with static destructors. However, have functions registered with + // `at_quick_exit` (for instance LLVM's code coverage profile dumping routine) + // be called before exiting. + quick_exit(status); } JNIEXPORT jstring JVM_NativeLoad(JNIEnv* env, diff --git a/perfetto_hprof/perfetto_hprof.cc b/perfetto_hprof/perfetto_hprof.cc index a27fc5ccc7..c718cc06b0 100644 --- a/perfetto_hprof/perfetto_hprof.cc +++ b/perfetto_hprof/perfetto_hprof.cc @@ -23,6 +23,7 @@ #include <inttypes.h> #include <sched.h> #include <signal.h> +#include <stdlib.h> #include <sys/socket.h> #include <sys/stat.h> #include <sys/types.h> @@ -913,8 +914,10 @@ void DumpPerfetto(art::Thread* self) { LOG(INFO) << "finished dumping heap for " << parent_pid; // Prevent the atexit handlers to run. We do not want to call cleanup - // functions the parent process has registered. - _exit(0); + // functions the parent process has registered. However, have functions + // registered with `at_quick_exit` (for instance LLVM's code coverage profile + // dumping routine) be called before exiting. + quick_exit(0); } // The plugin initialization function. diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def index e431183fb7..ef5bed7779 100644 --- a/runtime/runtime_options.def +++ b/runtime/runtime_options.def @@ -154,10 +154,12 @@ RUNTIME_OPTIONS_KEY (CompilerCallbacks*, CompilerCallbacksPtr) // TODO: make u RUNTIME_OPTIONS_KEY (bool (*)(), HookIsSensitiveThread) RUNTIME_OPTIONS_KEY (int32_t (*)(FILE* stream, const char* format, va_list ap), \ HookVfprintf, vfprintf) -// Use _exit instead of exit so that we won't get DCHECK failures in global data -// destructors. b/28106055. +// Use `quick_exit` instead of `exit` so that we won't get DCHECK failures +// in global data destructors (see b/28106055); but still have functions +// registered with `at_quick_exit` (for instance LLVM's code coverage profile +// dumping routine) be called before exiting. RUNTIME_OPTIONS_KEY (void (*)(int32_t status), \ - HookExit, _exit) + HookExit, quick_exit) // We don't call abort(3) by default; see // Runtime::Abort. RUNTIME_OPTIONS_KEY (void (*)(), HookAbort, nullptr) |