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") {
"android/java_exception_reporter.h",
"android/java_handler_thread.cc",
"android/java_handler_thread.h",
"android/java_heap_dump_generator.cc",
"android/java_heap_dump_generator.h",
"android/java_runtime.cc",
"android/java_runtime.h",
"android/jni_android.cc",
......@@ -3174,6 +3176,7 @@ if (is_android) {
"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/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/RecordUserAction.java",
"android/java/src/org/chromium/base/metrics/StatisticsRecorderAndroid.java",
......@@ -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/ChildProcessServiceDelegate.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/MemoryPressureCallback.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 @@
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/base/network_change_notifier.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/trace_event_agent.h"
#include "services/tracing/public/cpp/traced_process_impl.h"
......@@ -68,6 +67,7 @@
#include <sys/time.h>
#include "base/debug/elf_reader.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.
extern char __ehdr_start;
......@@ -212,8 +212,10 @@ void TracingControllerImpl::AddAgents() {
base::BindRepeating(&TracingDelegate::GenerateMetadataDict,
base::Unretained(delegate_.get())));
}
#if defined(OS_ANDROID)
tracing::PerfettoTracedProcess::Get()->AddDataSource(
tracing::JavaHeapProfiler::GetInstance());
#endif
}
void TracingControllerImpl::ConnectToServiceIfNeeded() {
......
......@@ -34,8 +34,8 @@ if (!is_nacl && !is_ios) {
"perfetto/dummy_producer.cc",
"perfetto/dummy_producer.h",
"perfetto/interning_index.h",
"perfetto/java_heap_profiler/java_heap_profiler.cc",
"perfetto/java_heap_profiler/java_heap_profiler.h",
"perfetto/java_heap_profiler/java_heap_profiler_android.cc",
"perfetto/java_heap_profiler/java_heap_profiler_android.h",
"perfetto/perfetto_config.cc",
"perfetto/perfetto_config.h",
"perfetto/perfetto_producer.cc",
......
......@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// 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"
namespace tracing {
......@@ -19,7 +21,18 @@ JavaHeapProfiler* JavaHeapProfiler::GetInstance() {
void JavaHeapProfiler::StartTracing(
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) {
producer_ = nullptr;
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_JAVA_HEAP_PROFILER_JAVA_HEAP_PROFILER_H_
#define 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_ANDROID_H_
#include "base/component_export.h"
#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
......@@ -29,4 +29,4 @@ class COMPONENT_EXPORT(TRACING_CPP) JavaHeapProfiler
};
} // 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