Commit 1c5e7cc1 authored by Etienne Pierre-doray's avatar Etienne Pierre-doray Committed by Commit Bot

[Clank SSM]: Support update of native modules from Unwinder.

As preparation for NativeUnwinderAndroid, ModuleCache needs to support adding
native modules.
This CL
- adds ModuleCache::AddCustomNativeModule.
- Renames Unwinder::AddNonNativeModule to Unwinder::AddInitialModules
- Turns android ChromeModule to a native module

Follow-up: https://chromium-review.googlesource.com/c/chromium/src/+/2055743

Bug: 989102
Change-Id: I5f2319e999f04e76de96702f811b3bfa50f5b17e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2080776Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarMike Wittman <wittman@chromium.org>
Commit-Queue: Etienne Pierre-Doray <etiennep@chromium.org>
Cr-Commit-Position: refs/heads/master@{#746909}
parent 1dd4504b
......@@ -74,7 +74,7 @@ class ChromeModule : public ModuleCache::Module {
}
// True if this is a native module.
bool IsNative() const override { return false; }
bool IsNative() const override { return true; }
std::string build_id_;
};
......@@ -88,7 +88,7 @@ ChromeUnwinderAndroid::ChromeUnwinderAndroid(const ArmCFITable* cfi_table)
ChromeUnwinderAndroid::~ChromeUnwinderAndroid() = default;
void ChromeUnwinderAndroid::AddNonNativeModules(ModuleCache* module_cache) {
void ChromeUnwinderAndroid::AddInitialModules(ModuleCache* module_cache) {
std::vector<std::unique_ptr<const ModuleCache::Module>> modules;
modules.push_back(std::make_unique<ChromeModule>());
chrome_module_id_ = modules.back()->GetId();
......
......@@ -26,7 +26,7 @@ class BASE_EXPORT ChromeUnwinderAndroid : public Unwinder {
void SetExpectedChromeModuleIdForTesting(const std::string& chrome_module_id);
// Unwinder:
void AddNonNativeModules(ModuleCache* module_cache) override;
void AddInitialModules(ModuleCache* module_cache) override;
bool CanUnwindFrom(const Frame* current_frame) const override;
UnwindResult TryUnwind(RegisterContext* thread_context,
uintptr_t stack_top,
......
......@@ -50,7 +50,7 @@ class TestModule : public ModuleCache::Module {
std::string GetId() const override { return build_id_; }
FilePath GetDebugBasename() const override { return FilePath(); }
size_t GetSize() const override { return size_; }
bool IsNative() const override { return false; }
bool IsNative() const override { return true; }
private:
const uintptr_t base_address_;
......@@ -58,15 +58,13 @@ class TestModule : public ModuleCache::Module {
const std::string build_id_;
};
// Utility function to add a single non-native module during test setup. Returns
// Utility function to add a single native module during test setup. Returns
// a pointer to the provided module.
const ModuleCache::Module* AddNonNativeModule(
const ModuleCache::Module* AddNativeModule(
ModuleCache* cache,
std::unique_ptr<const ModuleCache::Module> module) {
const ModuleCache::Module* module_ptr = module.get();
std::vector<std::unique_ptr<const ModuleCache::Module>> modules;
modules.push_back(std::move(module));
cache->UpdateNonNativeModules({}, std::move(modules));
cache->AddCustomNativeModule(std::move(module));
return module_ptr;
}
......@@ -230,7 +228,7 @@ TEST(ChromeUnwinderAndroidTest, TryUnwind) {
{reinterpret_cast<const uint8_t*>(cfi_data), sizeof(cfi_data)});
ModuleCache module_cache;
const ModuleCache::Module* chrome_module = AddNonNativeModule(
const ModuleCache::Module* chrome_module = AddNativeModule(
&module_cache, std::make_unique<TestModule>(0x1000, 0x500));
ChromeUnwinderAndroid unwinder(cfi_table.get());
......@@ -268,7 +266,7 @@ TEST(ChromeUnwinderAndroidTest, TryUnwindAbort) {
ASSERT_TRUE(cfi_table);
ModuleCache module_cache;
const ModuleCache::Module* chrome_module = AddNonNativeModule(
const ModuleCache::Module* chrome_module = AddNativeModule(
&module_cache, std::make_unique<TestModule>(0x1000, 0x500));
ChromeUnwinderAndroid unwinder(cfi_table.get());
......@@ -300,7 +298,7 @@ TEST(ChromeUnwinderAndroidTest, TryUnwindNoData) {
{reinterpret_cast<const uint8_t*>(cfi_data), sizeof(cfi_data)});
ModuleCache module_cache;
const ModuleCache::Module* chrome_module = AddNonNativeModule(
const ModuleCache::Module* chrome_module = AddNativeModule(
&module_cache, std::make_unique<TestModule>(0x1000, 0x500));
ChromeUnwinderAndroid unwinder(cfi_table.get());
......@@ -326,12 +324,12 @@ TEST(ChromeUnwinderAndroidTest, TryUnwindNoData) {
EXPECT_EQ(std::vector<Frame>({{0x1200, chrome_module}}), stack);
}
TEST(ChromeUnwinderAndroidTest, AddNonNativeModules) {
TEST(ChromeUnwinderAndroidTest, AddInitialModules) {
auto cfi_table = ArmCFITable::Parse(
{reinterpret_cast<const uint8_t*>(cfi_data), sizeof(cfi_data)});
ChromeUnwinderAndroid unwinder(cfi_table.get());
ModuleCache module_cache;
unwinder.AddNonNativeModules(&module_cache);
unwinder.AddInitialModules(&module_cache);
EXPECT_NE(module_cache.GetModuleForAddress(reinterpret_cast<uintptr_t>(
&ChromeUnwinderAndroid::StepForTesting)),
......
......@@ -93,8 +93,7 @@ void ModuleCache::UpdateNonNativeModules(
std::make_move_iterator(to_add.end()));
}
void ModuleCache::InjectNativeModuleForTesting(
std::unique_ptr<const Module> module) {
void ModuleCache::AddCustomNativeModule(std::unique_ptr<const Module> module) {
native_modules_.insert(std::move(module));
}
......
......@@ -93,7 +93,10 @@ class BASE_EXPORT ModuleCache {
const std::vector<const Module*>& to_remove,
std::vector<std::unique_ptr<const Module>> to_add);
void InjectNativeModuleForTesting(std::unique_ptr<const Module> module);
// Adds a custom native module to the cache. This is intended to support
// native modules that require custom handling. In general, native modules
// will be found and added automatically when invoking GetModuleForAddress().
void AddCustomNativeModule(std::unique_ptr<const Module> module);
private:
// Heterogenously compares modules by base address, and modules and
......
......@@ -111,7 +111,7 @@ MAYBE_TEST(ModuleCacheTest, LookupRange) {
ModuleCache cache;
auto to_inject = std::make_unique<IsolatedModule>();
const ModuleCache::Module* module = to_inject.get();
cache.InjectNativeModuleForTesting(std::move(to_inject));
cache.AddCustomNativeModule(std::move(to_inject));
EXPECT_EQ(nullptr, cache.GetModuleForAddress(module->GetBaseAddress() - 1));
EXPECT_EQ(module, cache.GetModuleForAddress(module->GetBaseAddress()));
......@@ -139,7 +139,7 @@ MAYBE_TEST(ModuleCacheTest, LookupOverlaidNonNativeModule) {
auto native_module_to_inject = std::make_unique<IsolatedModule>();
const ModuleCache::Module* native_module = native_module_to_inject.get();
cache.InjectNativeModuleForTesting(std::move(native_module_to_inject));
cache.AddCustomNativeModule(std::move(native_module_to_inject));
// Overlay the native module with the non-native module, starting 8 bytes into
// the native modules and ending 8 bytes before the end of the module.
......
......@@ -36,7 +36,7 @@ StackSamplerImpl::~StackSamplerImpl() = default;
void StackSamplerImpl::AddAuxUnwinder(std::unique_ptr<Unwinder> unwinder) {
aux_unwinder_ = std::move(unwinder);
aux_unwinder_->AddNonNativeModules(module_cache_);
aux_unwinder_->AddInitialModules(module_cache_);
}
void StackSamplerImpl::RecordStackFrames(StackBuffer* stack_buffer,
......
......@@ -155,7 +155,7 @@ std::vector<std::unique_ptr<const ModuleCache::Module>> ToModuleVector(
void InjectModuleForContextInstructionPointer(
const std::vector<uintptr_t>& stack,
ModuleCache* module_cache) {
module_cache->InjectNativeModuleForTesting(
module_cache->AddCustomNativeModule(
std::make_unique<TestModule>(stack[0], sizeof(uintptr_t)));
}
......@@ -271,8 +271,7 @@ TEST(StackSamplerImplTest, WalkStack_Completed) {
RegisterContext thread_context;
RegisterContextInstructionPointer(&thread_context) =
GetTestInstructionPointer();
module_cache.InjectNativeModuleForTesting(
std::make_unique<TestModule>(1u, 1u));
module_cache.AddCustomNativeModule(std::make_unique<TestModule>(1u, 1u));
FakeTestUnwinder native_unwinder({{UnwindResult::COMPLETED, {1u}}});
std::vector<Frame> stack = StackSamplerImpl::WalkStackForTesting(
......@@ -287,8 +286,7 @@ TEST(StackSamplerImplTest, WalkStack_Aborted) {
RegisterContext thread_context;
RegisterContextInstructionPointer(&thread_context) =
GetTestInstructionPointer();
module_cache.InjectNativeModuleForTesting(
std::make_unique<TestModule>(1u, 1u));
module_cache.AddCustomNativeModule(std::make_unique<TestModule>(1u, 1u));
FakeTestUnwinder native_unwinder({{UnwindResult::ABORTED, {1u}}});
std::vector<Frame> stack = StackSamplerImpl::WalkStackForTesting(
......@@ -343,8 +341,7 @@ TEST(StackSamplerImplTest, WalkStack_AuxThenNative) {
module_cache.UpdateNonNativeModules(
{}, ToModuleVector(std::make_unique<TestModule>(0u, 1u, false)));
// Inject a fake native module for the second frame.
module_cache.InjectNativeModuleForTesting(
std::make_unique<TestModule>(1u, 1u));
module_cache.AddCustomNativeModule(std::make_unique<TestModule>(1u, 1u));
FakeTestUnwinder aux_unwinder(
{{UnwindResult::UNRECOGNIZED_FRAME, {1u}}, false});
......@@ -366,10 +363,8 @@ TEST(StackSamplerImplTest, WalkStack_NativeThenAux) {
// Inject fake native modules for the instruction pointer from the context and
// the third frame.
module_cache.InjectNativeModuleForTesting(
std::make_unique<TestModule>(0u, 1u));
module_cache.InjectNativeModuleForTesting(
std::make_unique<TestModule>(2u, 1u));
module_cache.AddCustomNativeModule(std::make_unique<TestModule>(0u, 1u));
module_cache.AddCustomNativeModule(std::make_unique<TestModule>(2u, 1u));
// Treat the second frame's pointer as being in the aux unwinder's non-native
// module.
module_cache.UpdateNonNativeModules(
......
......@@ -37,9 +37,9 @@ class Unwinder {
public:
virtual ~Unwinder() = default;
// Invoked to allow the unwinder to add any non-native modules it recognizes
// to the ModuleCache.
virtual void AddNonNativeModules(ModuleCache* module_cache) {}
// Invoked to allow the unwinder to add any modules it recognizes to the
// ModuleCache.
virtual void AddInitialModules(ModuleCache* module_cache) {}
// Returns true if the unwinder recognizes the code referenced by
// |current_frame| as code from which it should be able to unwind. When
......
......@@ -51,7 +51,7 @@ V8Unwinder::V8Unwinder(const v8::UnwindState& unwind_state)
V8Unwinder::~V8Unwinder() = default;
void V8Unwinder::AddNonNativeModules(base::ModuleCache* module_cache) {
void V8Unwinder::AddInitialModules(base::ModuleCache* module_cache) {
std::vector<std::unique_ptr<const base::ModuleCache::Module>> modules;
modules.emplace_back(std::make_unique<V8Module>(
unwind_state_.embedded_code_range, kV8EmbeddedCodeRangeBuildId,
......
......@@ -20,7 +20,7 @@ class V8Unwinder : public base::Unwinder {
V8Unwinder& operator=(const V8Unwinder&) = delete;
// Unwinder:
void AddNonNativeModules(base::ModuleCache* module_cache) override;
void AddInitialModules(base::ModuleCache* module_cache) override;
bool CanUnwindFrom(const base::Frame* current_frame) const override;
base::UnwindResult TryUnwind(base::RegisterContext* thread_context,
uintptr_t stack_top,
......
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