Commit c805aa2d authored by Mike Wittman's avatar Mike Wittman Committed by Commit Bot

[Sampling profiler] Provide native access to module contents

Provides a native API to query/request module installation and provide
interfaces to the native code provided within the module. This API will
be used by native code along the lines described in the design doc at
https://docs.google.com/document/d/1QB5IzWuVKfoPdPuiyRok2MUEta1FmRLIQkq1wDATA4k.

Bug: 1027654
Change-Id: I52fb0a4cfbec06dd603617ed1949fa20fda6ef03
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2003299Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Reviewed-by: default avatarEtienne Pierre-Doray <etiennep@chromium.org>
Reviewed-by: default avatarSamuel Huang <huangs@chromium.org>
Commit-Queue: Mike Wittman <wittman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#738283}
parent 535b1cb8
# Copyright 2020 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.
source_set("memory_regions_map") {
public = [ "memory_regions_map.h" ]
}
// Copyright 2020 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 CHROME_ANDROID_FEATURES_STACK_UNWINDER_PUBLIC_MEMORY_REGIONS_MAP_H_
#define CHROME_ANDROID_FEATURES_STACK_UNWINDER_PUBLIC_MEMORY_REGIONS_MAP_H_
namespace stack_unwinder {
// MemoryRegionsMap is intended to provide an opaque interface to Chrome code.
// It must only be subclassed within the module implementation.
class MemoryRegionsMap {
public:
virtual ~MemoryRegionsMap() = 0;
};
} // namespace stack_unwinder
#endif // CHROME_ANDROID_FEATURES_STACK_UNWINDER_PUBLIC_MEMORY_REGIONS_MAP_H_
...@@ -23,7 +23,10 @@ group("native") { ...@@ -23,7 +23,10 @@ group("native") {
component("stack_unwinder") { component("stack_unwinder") {
sources = [ "entrypoints.cc" ] sources = [ "entrypoints.cc" ]
deps = [ "//base" ] deps = [
"//base",
"//chrome/android/features/stack_unwinder/public:memory_regions_map",
]
# stack unwinder native entrypoints belong in the partition. # stack unwinder native entrypoints belong in the partition.
if (use_native_partitions) { if (use_native_partitions) {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "base/android/jni_generator/jni_generator_helper.h" #include "base/android/jni_generator/jni_generator_helper.h"
#include "base/android/jni_utils.h" #include "base/android/jni_utils.h"
#include "base/profiler/unwinder.h" #include "base/profiler/unwinder.h"
#include "chrome/android/features/stack_unwinder/public/memory_regions_map.h"
extern "C" { extern "C" {
// This JNI registration method is found and called by module framework // This JNI registration method is found and called by module framework
...@@ -13,4 +14,24 @@ JNI_GENERATOR_EXPORT bool JNI_OnLoad_stack_unwinder(JNIEnv* env) { ...@@ -13,4 +14,24 @@ JNI_GENERATOR_EXPORT bool JNI_OnLoad_stack_unwinder(JNIEnv* env) {
return true; return true;
} }
// Native entry point functions.
// Creates a new memory regions map. The caller takes ownership of the returned
// object. We can't use std::unique_ptr here because this function has C
// linkage.
__attribute__((visibility("default"))) stack_unwinder::MemoryRegionsMap*
CreateMemoryRegionsMap() {
// TODO(etiennep): Implement.
return nullptr;
}
// Creates a new native unwinder. The caller takes ownership of the returned
// object. We can't use std::unique_ptr here because this function has C
// linkage.
__attribute__((visibility("default"))) base::Unwinder* CreateNativeUnwinder(
stack_unwinder::MemoryRegionsMap* memory_regions_map) {
// TODO(etiennep): Implement.
return nullptr;
}
} // extern "C" } // extern "C"
...@@ -14,3 +14,14 @@ android_library("java") { ...@@ -14,3 +14,14 @@ android_library("java") {
annotation_processor_deps = annotation_processor_deps =
[ "//components/module_installer/android:module_interface_processor" ] [ "//components/module_installer/android:module_interface_processor" ]
} }
source_set("module") {
public = [ "module.h" ]
sources = [ "module.cc" ]
deps = [
"//base",
"//chrome/android/features/stack_unwinder/public:memory_regions_map",
"//chrome/android/modules/stack_unwinder/provider:jni_headers",
]
libs = [ "dl" ]
}
// Copyright 2020 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 "chrome/android/modules/stack_unwinder/public/module.h"
#include <dlfcn.h>
#include "base/android/bundle_utils.h"
#include "base/android/jni_android.h"
#include "base/memory/ptr_util.h"
#include "base/strings/strcat.h"
#include "chrome/android/modules/stack_unwinder/provider/jni_headers/StackUnwinderModuleProvider_jni.h"
namespace stack_unwinder {
namespace {
void* TryLoadModule() {
const char* chrome_target_possibilities[] = {
"monochrome",
"chrome",
};
const char partition_name[] = "stack_unwinder_partition";
for (const char* target : chrome_target_possibilities) {
void* module = base::android::BundleUtils::DlOpenModuleLibraryPartition(
base::StrCat({target, "_", partition_name}), partition_name);
if (module)
return module;
}
return nullptr;
}
} // namespace
// static
bool Module::IsInstalled() {
JNIEnv* env = base::android::AttachCurrentThread();
return Java_StackUnwinderModuleProvider_isModuleInstalled(env);
}
// static
void Module::RequestInstallation() {
JNIEnv* env = base::android::AttachCurrentThread();
Java_StackUnwinderModuleProvider_installModule(env);
}
// static
std::unique_ptr<Module> Module::TryLoad() {
void* module = TryLoadModule();
if (!module)
return nullptr;
CreateMemoryRegionsMapFunction create_memory_regions_map =
reinterpret_cast<CreateMemoryRegionsMapFunction>(
dlsym(module, "CreateMemoryRegionsMap"));
CHECK(create_memory_regions_map);
CreateNativeUnwinderFunction create_native_unwinder =
reinterpret_cast<CreateNativeUnwinderFunction>(
dlsym(module, "CreateNativeUnwinder"));
CHECK(create_native_unwinder);
return base::WrapUnique(
new Module(create_memory_regions_map, create_native_unwinder));
}
std::unique_ptr<MemoryRegionsMap> Module::CreateMemoryRegionsMap() {
return base::WrapUnique(create_memory_regions_map_());
}
std::unique_ptr<base::Unwinder> Module::CreateNativeUnwinder(
MemoryRegionsMap* memory_regions_map) {
return base::WrapUnique(create_native_unwinder_(memory_regions_map));
}
Module::Module(CreateMemoryRegionsMapFunction create_memory_regions_map,
CreateNativeUnwinderFunction create_native_unwinder)
: create_memory_regions_map_(create_memory_regions_map),
create_native_unwinder_(create_native_unwinder) {}
} // namespace stack_unwinder
// Copyright 2020 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 CHROME_ANDROID_MODULES_STACK_UNWINDER_PUBLIC_MODULE_H_
#define CHROME_ANDROID_MODULES_STACK_UNWINDER_PUBLIC_MODULE_H_
#include <memory>
#include "base/profiler/unwinder.h"
#include "chrome/android/features/stack_unwinder/public/memory_regions_map.h"
namespace stack_unwinder {
// Provides access to the stack_unwinder module.
class Module {
public:
Module(const Module&) = delete;
Module& operator=(const Module&) = delete;
// Returns true if the module is installed.
static bool IsInstalled();
// Requests asynchronous installation of the module. This is a no-op if the
// module is already installed.
static void RequestInstallation();
// Attempts to load the module. Returns non-null if IsInstalled().
static std::unique_ptr<Module> TryLoad();
// Returns a map representing the current memory regions (modules, stacks,
// etc.).
std::unique_ptr<MemoryRegionsMap> CreateMemoryRegionsMap();
// Creates a new native stack unwinder.
std::unique_ptr<base::Unwinder> CreateNativeUnwinder(
MemoryRegionsMap* memory_regions_map);
private:
using CreateMemoryRegionsMapFunction = MemoryRegionsMap* (*)();
using CreateNativeUnwinderFunction = base::Unwinder* (*)(MemoryRegionsMap*);
Module(CreateMemoryRegionsMapFunction create_memory_regions_map,
CreateNativeUnwinderFunction create_native_unwinder);
const CreateMemoryRegionsMapFunction create_memory_regions_map_;
const CreateNativeUnwinderFunction create_native_unwinder_;
};
} // namespace stack_unwinder
#endif // CHROME_ANDROID_MODULES_STACK_UNWINDER_PUBLIC_MODULE_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