summaryrefslogtreecommitdiffstats
path: root/runtime/native/dalvik_system_ZygoteHooks.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/native/dalvik_system_ZygoteHooks.cc')
-rw-r--r--runtime/native/dalvik_system_ZygoteHooks.cc52
1 files changed, 52 insertions, 0 deletions
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index 022c56f..af01a02 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -18,14 +18,18 @@
#include <stdlib.h>
+#include <cutils/process_name.h>
+
#include "arch/instruction_set.h"
#include "debugger.h"
#include "java_vm_ext.h"
#include "jit/jit.h"
#include "jni_internal.h"
#include "JNIHelp.h"
+#include "scoped_thread_state_change.h"
#include "ScopedUtfChars.h"
#include "thread-inl.h"
+#include "trace.h"
#if defined(__linux__)
#include <sys/prctl.h>
@@ -121,6 +125,11 @@ static jlong ZygoteHooks_nativePreFork(JNIEnv* env, jclass) {
runtime->PreZygoteFork();
+ if (Trace::GetMethodTracingMode() != TracingMode::kTracingInactive) {
+ // Tracing active, pause it.
+ Trace::Pause();
+ }
+
// Grab thread before fork potentially makes Thread::pthread_key_self_ unusable.
return reinterpret_cast<jlong>(ThreadForEnv(env));
}
@@ -132,6 +141,49 @@ static void ZygoteHooks_nativePostForkChild(JNIEnv* env, jclass, jlong token, ji
thread->InitAfterFork();
EnableDebugFeatures(debug_flags);
+ // Update tracing.
+ if (Trace::GetMethodTracingMode() != TracingMode::kTracingInactive) {
+ Trace::TraceOutputMode output_mode = Trace::GetOutputMode();
+ Trace::TraceMode trace_mode = Trace::GetMode();
+
+ // Just drop it.
+ Trace::Abort();
+
+ // Only restart if it was streaming mode.
+ // TODO: Expose buffer size, so we can also do file mode.
+ if (output_mode == Trace::TraceOutputMode::kStreaming) {
+ const char* proc_name_cutils = get_process_name();
+ std::string proc_name;
+ if (proc_name_cutils != nullptr) {
+ proc_name = proc_name_cutils;
+ }
+ if (proc_name_cutils == nullptr || proc_name == "zygote" || proc_name == "zygote64") {
+ // Either no process name, or the name hasn't been changed, yet. Just use pid.
+ pid_t pid = getpid();
+ proc_name = StringPrintf("%u", static_cast<uint32_t>(pid));
+ }
+
+ std::string profiles_dir(GetDalvikCache("profiles", false /* create_if_absent */));
+ if (!profiles_dir.empty()) {
+ std::string trace_file = StringPrintf("%s/%s.trace.bin", profiles_dir.c_str(),
+ proc_name.c_str());
+ Trace::Start(trace_file.c_str(),
+ -1,
+ -1, // TODO: Expose buffer size.
+ 0, // TODO: Expose flags.
+ output_mode,
+ trace_mode,
+ 0); // TODO: Expose interval.
+ if (thread->IsExceptionPending()) {
+ ScopedObjectAccess soa(env);
+ thread->ClearException();
+ }
+ } else {
+ LOG(ERROR) << "Profiles dir is empty?!?!";
+ }
+ }
+ }
+
if (instruction_set != nullptr) {
ScopedUtfChars isa_string(env, instruction_set);
InstructionSet isa = GetInstructionSetFromString(isa_string.c_str());