Commit 20ae8f2e authored by George Zhang's avatar George Zhang Committed by Commit Bot

Add Java method to generate heap dumps and corresponding native method in C++

Currently, nothing in the codebase exists to generate java heap dumps.

By adding this, we write heap dumps to file that can be passed to c++
which can be later uploaded and analyzed.

Bug: 1012072

Change-Id: I9381b998d3fc98d2efa7f226e3c0b0b25dd4f3ed
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1839011
Commit-Queue: ssid <ssid@chromium.org>
Reviewed-by: default avatarssid <ssid@chromium.org>
Reviewed-by: default avatarTommy Nyquist <nyquist@chromium.org>
Cr-Commit-Position: refs/heads/master@{#706077}
parent a9df5b29
...@@ -1376,6 +1376,8 @@ jumbo_component("base") { ...@@ -1376,6 +1376,8 @@ jumbo_component("base") {
"android/java_exception_reporter.h", "android/java_exception_reporter.h",
"android/java_handler_thread.cc", "android/java_handler_thread.cc",
"android/java_handler_thread.h", "android/java_handler_thread.h",
"android/java_heap_dump_generator.cc",
"android/java_heap_dump_generator.h",
"android/java_runtime.cc", "android/java_runtime.cc",
"android/java_runtime.h", "android/java_runtime.h",
"android/jni_android.cc", "android/jni_android.cc",
...@@ -3174,6 +3176,7 @@ if (is_android) { ...@@ -3174,6 +3176,7 @@ if (is_android) {
"android/java/src/org/chromium/base/UnguessableToken.java", "android/java/src/org/chromium/base/UnguessableToken.java",
"android/java/src/org/chromium/base/library_loader/LibraryLoader.java", "android/java/src/org/chromium/base/library_loader/LibraryLoader.java",
"android/java/src/org/chromium/base/library_loader/LibraryPrefetcher.java", "android/java/src/org/chromium/base/library_loader/LibraryPrefetcher.java",
"android/java/src/org/chromium/base/memory/JavaHeapDumpGenerator.java",
"android/java/src/org/chromium/base/metrics/RecordHistogram.java", "android/java/src/org/chromium/base/metrics/RecordHistogram.java",
"android/java/src/org/chromium/base/metrics/RecordUserAction.java", "android/java/src/org/chromium/base/metrics/RecordUserAction.java",
"android/java/src/org/chromium/base/metrics/StatisticsRecorderAndroid.java", "android/java/src/org/chromium/base/metrics/StatisticsRecorderAndroid.java",
...@@ -3323,6 +3326,7 @@ if (is_android) { ...@@ -3323,6 +3326,7 @@ if (is_android) {
"android/java/src/org/chromium/base/process_launcher/ChildProcessService.java", "android/java/src/org/chromium/base/process_launcher/ChildProcessService.java",
"android/java/src/org/chromium/base/process_launcher/ChildProcessServiceDelegate.java", "android/java/src/org/chromium/base/process_launcher/ChildProcessServiceDelegate.java",
"android/java/src/org/chromium/base/process_launcher/FileDescriptorInfo.java", "android/java/src/org/chromium/base/process_launcher/FileDescriptorInfo.java",
"android/java/src/org/chromium/base/memory/JavaHeapDumpGenerator.java",
"android/java/src/org/chromium/base/memory/MemoryPressureMonitor.java", "android/java/src/org/chromium/base/memory/MemoryPressureMonitor.java",
"android/java/src/org/chromium/base/memory/MemoryPressureCallback.java", "android/java/src/org/chromium/base/memory/MemoryPressureCallback.java",
"android/java/src/org/chromium/base/memory/MemoryPressureUma.java", "android/java/src/org/chromium/base/memory/MemoryPressureUma.java",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.base.memory;
import android.os.Debug;
import org.chromium.base.Log;
import org.chromium.base.annotations.CalledByNative;
import java.io.IOException;
/**
* Enables the generation of hprof files from heap dumps.
*/
public final class JavaHeapDumpGenerator {
private static final String TAG = "JavaHprofGenerator";
private JavaHeapDumpGenerator() {}
/**
* Generates an hprof file at the given filePath.
* @param filePath
* @return whether or not the hprof file was properly generated.
*/
@CalledByNative
public static boolean generateHprof(String filePath) {
try {
Debug.dumpHprofData(filePath);
} catch (IOException e) {
Log.i(TAG, "Error writing to file " + filePath + ". Error: " + e.getMessage());
return false;
}
return true;
}
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/android/java_heap_dump_generator.h"
#include <jni.h>
#include "base/android/jni_string.h"
#include "base/base_jni_headers/JavaHeapDumpGenerator_jni.h"
namespace base {
namespace android {
bool WriteJavaHeapDumpToPath(base::StringPiece filePath) {
JNIEnv* env = AttachCurrentThread();
return Java_JavaHeapDumpGenerator_generateHprof(
env, base::android::ConvertUTF8ToJavaString(env, filePath));
}
} // namespace android
} // namespace base
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_ANDROID_JAVA_HEAP_DUMP_GENERATOR_H_
#define BASE_ANDROID_JAVA_HEAP_DUMP_GENERATOR_H_
#include <string>
#include "base/android/scoped_java_ref.h"
#include "base/base_export.h"
namespace base {
namespace android {
// Generates heap dump and writes it to a file at |file_path|. Returns true on
// success. The heap dump is generated through the Android Java system API
// android.os.Debug#dumpHprofData(...)
BASE_EXPORT bool WriteJavaHeapDumpToPath(base::StringPiece file_path);
} // namespace android
} // namespace base
#endif // BASE_ANDROID_JAVA_HEAP_DUMP_GENERATOR_H_
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
#include "mojo/public/cpp/system/data_pipe.h" #include "mojo/public/cpp/system/data_pipe.h"
#include "net/base/network_change_notifier.h" #include "net/base/network_change_notifier.h"
#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/connector.h"
#include "services/tracing/public/cpp/perfetto/java_heap_profiler/java_heap_profiler.h"
#include "services/tracing/public/cpp/perfetto/perfetto_config.h" #include "services/tracing/public/cpp/perfetto/perfetto_config.h"
#include "services/tracing/public/cpp/trace_event_agent.h" #include "services/tracing/public/cpp/trace_event_agent.h"
#include "services/tracing/public/cpp/traced_process_impl.h" #include "services/tracing/public/cpp/traced_process_impl.h"
...@@ -68,6 +67,7 @@ ...@@ -68,6 +67,7 @@
#include <sys/time.h> #include <sys/time.h>
#include "base/debug/elf_reader.h" #include "base/debug/elf_reader.h"
#include "content/browser/android/tracing_controller_android.h" #include "content/browser/android/tracing_controller_android.h"
#include "services/tracing/public/cpp/perfetto/java_heap_profiler/java_heap_profiler_android.h"
// Symbol with virtual address of the start of ELF header of the current binary. // Symbol with virtual address of the start of ELF header of the current binary.
extern char __ehdr_start; extern char __ehdr_start;
...@@ -212,8 +212,10 @@ void TracingControllerImpl::AddAgents() { ...@@ -212,8 +212,10 @@ void TracingControllerImpl::AddAgents() {
base::BindRepeating(&TracingDelegate::GenerateMetadataDict, base::BindRepeating(&TracingDelegate::GenerateMetadataDict,
base::Unretained(delegate_.get()))); base::Unretained(delegate_.get())));
} }
#if defined(OS_ANDROID)
tracing::PerfettoTracedProcess::Get()->AddDataSource( tracing::PerfettoTracedProcess::Get()->AddDataSource(
tracing::JavaHeapProfiler::GetInstance()); tracing::JavaHeapProfiler::GetInstance());
#endif
} }
void TracingControllerImpl::ConnectToServiceIfNeeded() { void TracingControllerImpl::ConnectToServiceIfNeeded() {
......
...@@ -34,8 +34,8 @@ if (!is_nacl && !is_ios) { ...@@ -34,8 +34,8 @@ if (!is_nacl && !is_ios) {
"perfetto/dummy_producer.cc", "perfetto/dummy_producer.cc",
"perfetto/dummy_producer.h", "perfetto/dummy_producer.h",
"perfetto/interning_index.h", "perfetto/interning_index.h",
"perfetto/java_heap_profiler/java_heap_profiler.cc", "perfetto/java_heap_profiler/java_heap_profiler_android.cc",
"perfetto/java_heap_profiler/java_heap_profiler.h", "perfetto/java_heap_profiler/java_heap_profiler_android.h",
"perfetto/perfetto_config.cc", "perfetto/perfetto_config.cc",
"perfetto/perfetto_config.h", "perfetto/perfetto_config.h",
"perfetto/perfetto_producer.cc", "perfetto/perfetto_producer.cc",
......
...@@ -2,8 +2,10 @@ ...@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "services/tracing/public/cpp/perfetto/java_heap_profiler/java_heap_profiler.h" #include "services/tracing/public/cpp/perfetto/java_heap_profiler/java_heap_profiler_android.h"
#include "base/android/java_heap_dump_generator.h"
#include "base/files/scoped_temp_dir.h"
#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h" #include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
namespace tracing { namespace tracing {
...@@ -19,7 +21,18 @@ JavaHeapProfiler* JavaHeapProfiler::GetInstance() { ...@@ -19,7 +21,18 @@ JavaHeapProfiler* JavaHeapProfiler::GetInstance() {
void JavaHeapProfiler::StartTracing( void JavaHeapProfiler::StartTracing(
PerfettoProducer* producer, PerfettoProducer* producer,
const perfetto::DataSourceConfig& data_source_config) {} const perfetto::DataSourceConfig& data_source_config) {
base::ScopedTempDir temp_dir;
if (!temp_dir.CreateUniqueTempDir()) {
VLOG(0) << "Failed to create unique temporary directory.";
return;
}
std::string file_path = temp_dir.GetPath().Append("temp_hprof.hprof").value();
base::android::WriteJavaHeapDumpToPath(file_path);
// TODO(zhanggeorge): Convert heap dump and write to trace.
}
void JavaHeapProfiler::StopTracing(base::OnceClosure stop_complete_callback) { void JavaHeapProfiler::StopTracing(base::OnceClosure stop_complete_callback) {
producer_ = nullptr; producer_ = nullptr;
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_JAVA_HEAP_PROFILER_JAVA_HEAP_PROFILER_H_ #ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_JAVA_HEAP_PROFILER_JAVA_HEAP_PROFILER_ANDROID_H_
#define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_JAVA_HEAP_PROFILER_JAVA_HEAP_PROFILER_H_ #define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_JAVA_HEAP_PROFILER_JAVA_HEAP_PROFILER_ANDROID_H_
#include "base/component_export.h" #include "base/component_export.h"
#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h" #include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
...@@ -29,4 +29,4 @@ class COMPONENT_EXPORT(TRACING_CPP) JavaHeapProfiler ...@@ -29,4 +29,4 @@ class COMPONENT_EXPORT(TRACING_CPP) JavaHeapProfiler
}; };
} // namespace tracing } // namespace tracing
#endif // SERVICES_TRACING_PUBLIC_CPP_PERFETTO_JAVA_HEAP_PROFILER_JAVA_HEAP_PROFILER_H_ #endif // SERVICES_TRACING_PUBLIC_CPP_PERFETTO_JAVA_HEAP_PROFILER_JAVA_HEAP_PROFILER_ANDROID_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment