mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-30 17:21:10 +00:00
Revert "Revert "[lldb][LocateModuleCallback] Call locate module callback""
This reverts commit df054499c3
.
Reverting because of build errors
In file included from /Users/buildslave/jenkins/workspace/as-lldb-cmake/llvm-project/lldb/source/API/SBPlatform.cpp:19:
/Users/buildslave/jenkins/workspace/as-lldb-cmake/llvm-project/lldb/include/lldb/Target/Target.h:1035:18: warning: parameter 'merged' not found in the function declaration [-Wdocumentation]
This commit is contained in:
parent
be794e3d92
commit
55147ceb62
@ -881,6 +881,19 @@ public:
|
||||
|
||||
virtual Args GetExtraStartupCommands();
|
||||
|
||||
typedef std::function<Status(const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec)>
|
||||
LocateModuleCallback;
|
||||
|
||||
/// Set locate module callback. This allows users to implement their own
|
||||
/// module cache system. For example, to leverage artifacts of build system,
|
||||
/// to bypass pulling files from remote platform, or to search symbol files
|
||||
/// from symbol servers.
|
||||
void SetLocateModuleCallback(LocateModuleCallback callback);
|
||||
|
||||
LocateModuleCallback GetLocateModuleCallback() const;
|
||||
|
||||
protected:
|
||||
/// Create a list of ArchSpecs with the given OS and a architectures. The
|
||||
/// vendor field is left as an "unspecified unknown".
|
||||
@ -928,6 +941,7 @@ protected:
|
||||
std::vector<ConstString> m_trap_handlers;
|
||||
bool m_calculated_trap_handlers;
|
||||
const std::unique_ptr<ModuleCache> m_module_cache;
|
||||
LocateModuleCallback m_locate_module_callback;
|
||||
|
||||
/// Ask the Platform subclass to fill in the list of trap handler names
|
||||
///
|
||||
|
@ -1625,6 +1625,12 @@ private:
|
||||
|
||||
Target(const Target &) = delete;
|
||||
const Target &operator=(const Target &) = delete;
|
||||
|
||||
private:
|
||||
void CallLocateModuleCallbackIfSet(const ModuleSpec &module_spec,
|
||||
lldb::ModuleSP &module_sp,
|
||||
FileSpec &symbol_file_spec,
|
||||
bool &did_create_module);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
@ -1971,6 +1971,14 @@ Args Platform::GetExtraStartupCommands() {
|
||||
return {};
|
||||
}
|
||||
|
||||
void Platform::SetLocateModuleCallback(LocateModuleCallback callback) {
|
||||
m_locate_module_callback = callback;
|
||||
}
|
||||
|
||||
Platform::LocateModuleCallback Platform::GetLocateModuleCallback() const {
|
||||
return m_locate_module_callback;
|
||||
}
|
||||
|
||||
PlatformSP PlatformList::GetOrCreate(llvm::StringRef name) {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
||||
for (const PlatformSP &platform_sp : m_platforms) {
|
||||
|
@ -2129,19 +2129,46 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify,
|
||||
// of the library
|
||||
bool did_create_module = false;
|
||||
FileSpecList search_paths = GetExecutableSearchPaths();
|
||||
// If there are image search path entries, try to use them first to acquire
|
||||
// a suitable image.
|
||||
if (m_image_search_paths.GetSize()) {
|
||||
ModuleSpec transformed_spec(module_spec);
|
||||
ConstString transformed_dir;
|
||||
if (m_image_search_paths.RemapPath(
|
||||
module_spec.GetFileSpec().GetDirectory(), transformed_dir)) {
|
||||
transformed_spec.GetFileSpec().SetDirectory(transformed_dir);
|
||||
transformed_spec.GetFileSpec().SetFilename(
|
||||
module_spec.GetFileSpec().GetFilename());
|
||||
error = ModuleList::GetSharedModule(transformed_spec, module_sp,
|
||||
&search_paths, &old_modules,
|
||||
&did_create_module);
|
||||
FileSpec symbol_file_spec;
|
||||
|
||||
// Call locate module callback if set. This allows users to implement their
|
||||
// own module cache system. For example, to leverage build system artifacts,
|
||||
// to bypass pulling files from remote platform, or to search symbol files
|
||||
// from symbol servers.
|
||||
CallLocateModuleCallbackIfSet(module_spec, module_sp, symbol_file_spec,
|
||||
did_create_module);
|
||||
|
||||
// The result of this CallLocateModuleCallbackIfSet is one of the following.
|
||||
// 1. module_sp:loaded, symbol_file_spec:set
|
||||
// The callback found a module file and a symbol file for the
|
||||
// module_spec. We will call module_sp->SetSymbolFileFileSpec with
|
||||
// the symbol_file_spec later.
|
||||
// 2. module_sp:loaded, symbol_file_spec:empty
|
||||
// The callback only found a module file for the module_spec.
|
||||
// 3. module_sp:empty, symbol_file_spec:set
|
||||
// The callback only found a symbol file for the module. We continue
|
||||
// to find a module file for this module_spec and we will call
|
||||
// module_sp->SetSymbolFileFileSpec with the symbol_file_spec later.
|
||||
// 4. module_sp:empty, symbol_file_spec:empty
|
||||
// The callback is not set. Or the callback did not find any module
|
||||
// files nor any symbol files. Or the callback failed, or something
|
||||
// went wrong. We continue to find a module file for this module_spec.
|
||||
|
||||
if (!module_sp) {
|
||||
// If there are image search path entries, try to use them to acquire a
|
||||
// suitable image.
|
||||
if (m_image_search_paths.GetSize()) {
|
||||
ModuleSpec transformed_spec(module_spec);
|
||||
ConstString transformed_dir;
|
||||
if (m_image_search_paths.RemapPath(
|
||||
module_spec.GetFileSpec().GetDirectory(), transformed_dir)) {
|
||||
transformed_spec.GetFileSpec().SetDirectory(transformed_dir);
|
||||
transformed_spec.GetFileSpec().SetFilename(
|
||||
module_spec.GetFileSpec().GetFilename());
|
||||
error = ModuleList::GetSharedModule(transformed_spec, module_sp,
|
||||
&search_paths, &old_modules,
|
||||
&did_create_module);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2232,6 +2259,11 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify,
|
||||
});
|
||||
}
|
||||
|
||||
// If the locate module callback had found a symbol file, set it to the
|
||||
// module_sp before preloading symbols.
|
||||
if (symbol_file_spec)
|
||||
module_sp->SetSymbolFileFileSpec(symbol_file_spec);
|
||||
|
||||
// Preload symbols outside of any lock, so hopefully we can do this for
|
||||
// each library in parallel.
|
||||
if (GetPreloadSymbols())
|
||||
@ -2306,6 +2338,113 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify,
|
||||
return module_sp;
|
||||
}
|
||||
|
||||
void Target::CallLocateModuleCallbackIfSet(const ModuleSpec &module_spec,
|
||||
lldb::ModuleSP &module_sp,
|
||||
FileSpec &symbol_file_spec,
|
||||
bool &did_create_module) {
|
||||
if (!m_platform_sp)
|
||||
return;
|
||||
|
||||
Platform::LocateModuleCallback locate_module_callback =
|
||||
m_platform_sp->GetLocateModuleCallback();
|
||||
if (!locate_module_callback)
|
||||
return;
|
||||
|
||||
FileSpec module_file_spec;
|
||||
Status error =
|
||||
locate_module_callback(module_spec, module_file_spec, symbol_file_spec);
|
||||
|
||||
// Locate module callback is set and called. Check the error.
|
||||
Log *log = GetLog(LLDBLog::Target);
|
||||
if (error.Fail()) {
|
||||
LLDB_LOGF(log, "%s: locate module callback failed: %s",
|
||||
LLVM_PRETTY_FUNCTION, error.AsCString());
|
||||
return;
|
||||
}
|
||||
|
||||
// The locate module callback was succeeded. It should returned
|
||||
// 1. a combination of a module file and a symbol file.
|
||||
// 2. or only a module file.
|
||||
// 3. or only a symbol file. For example, a breakpad symbol text file.
|
||||
//
|
||||
// Check the module_file_spec and symbol_file_spec values.
|
||||
// 1. module:empty symbol:empty -> Invalid
|
||||
// 2. module:exists symbol:exists -> Success
|
||||
// 3. module:exists symbol:empty -> Success
|
||||
// 4. module:empty symbol:exists -> Success
|
||||
if (!module_file_spec && !symbol_file_spec) {
|
||||
// This is '1. module:empty symbol:empty -> Invalid'.
|
||||
LLDB_LOGF(log,
|
||||
"%s: locate module callback did not set both "
|
||||
"module_file_spec and symbol_file_spec",
|
||||
LLVM_PRETTY_FUNCTION);
|
||||
return;
|
||||
}
|
||||
|
||||
// The module file should exist.
|
||||
if (module_file_spec && !FileSystem::Instance().Exists(module_file_spec)) {
|
||||
LLDB_LOGF(log,
|
||||
"%s: locate module callback set a non-existent file to "
|
||||
"module_file_spec: %s",
|
||||
LLVM_PRETTY_FUNCTION, module_file_spec.GetPath().c_str());
|
||||
// Clear symbol_file_spec for the error.
|
||||
symbol_file_spec.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// The symbol file should exist.
|
||||
if (symbol_file_spec && !FileSystem::Instance().Exists(symbol_file_spec)) {
|
||||
LLDB_LOGF(log,
|
||||
"%s: locate module callback set a non-existent file to "
|
||||
"symbol_file_spec: %s",
|
||||
LLVM_PRETTY_FUNCTION, symbol_file_spec.GetPath().c_str());
|
||||
// Clear symbol_file_spec for the error.
|
||||
symbol_file_spec.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!module_file_spec && symbol_file_spec) {
|
||||
// This is '4. module:empty symbol:exists -> Success'.
|
||||
// The locate module callback returned only a symbol file. For example,
|
||||
// a breakpad symbol text file. GetOrCreateModule will use this returned
|
||||
// symbol_file_spec.
|
||||
LLDB_LOGF(log, "%s: locate module callback succeeded: symbol=%s",
|
||||
LLVM_PRETTY_FUNCTION, symbol_file_spec.GetPath().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// The locate module callback returned
|
||||
// - '2. module:exists symbol:exists -> Success'
|
||||
// - a combination of a module file and a symbol file.
|
||||
// - Or '3. module:exists symbol:empty -> Success'
|
||||
// - only a module file.
|
||||
// Load the module file.
|
||||
auto cached_module_spec(module_spec);
|
||||
cached_module_spec.GetUUID().Clear(); // Clear UUID since it may contain md5
|
||||
// content hash instead of real UUID.
|
||||
cached_module_spec.GetFileSpec() = module_file_spec;
|
||||
cached_module_spec.GetPlatformFileSpec() = module_spec.GetFileSpec();
|
||||
cached_module_spec.SetObjectOffset(0);
|
||||
|
||||
error = ModuleList::GetSharedModule(cached_module_spec, module_sp, nullptr,
|
||||
nullptr, &did_create_module, false);
|
||||
if (error.Success() && module_sp) {
|
||||
// Succeeded to load the module file.
|
||||
LLDB_LOGF(log, "%s: locate module callback succeeded: module=%s symbol=%s",
|
||||
LLVM_PRETTY_FUNCTION, module_file_spec.GetPath().c_str(),
|
||||
symbol_file_spec.GetPath().c_str());
|
||||
} else {
|
||||
LLDB_LOGF(log,
|
||||
"%s: locate module callback succeeded but failed to load: "
|
||||
"module=%s symbol=%s",
|
||||
LLVM_PRETTY_FUNCTION, module_file_spec.GetPath().c_str(),
|
||||
symbol_file_spec.GetPath().c_str());
|
||||
// Clear module_sp and symbol_file_spec for the error.
|
||||
module_sp.reset();
|
||||
symbol_file_spec.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
TargetSP Target::CalculateTarget() { return shared_from_this(); }
|
||||
|
||||
ProcessSP Target::CalculateProcess() { return m_process_sp; }
|
||||
|
@ -2,6 +2,7 @@ add_lldb_unittest(TargetTests
|
||||
ABITest.cpp
|
||||
DynamicRegisterInfoTest.cpp
|
||||
ExecutionContextTest.cpp
|
||||
LocateModuleCallbackTest.cpp
|
||||
MemoryRegionInfoTest.cpp
|
||||
MemoryTest.cpp
|
||||
MemoryTagMapTest.cpp
|
||||
@ -15,9 +16,12 @@ add_lldb_unittest(TargetTests
|
||||
LINK_LIBS
|
||||
lldbCore
|
||||
lldbHost
|
||||
lldbPluginObjectFileBreakpad
|
||||
lldbPluginObjectFileELF
|
||||
lldbPluginPlatformLinux
|
||||
lldbPluginPlatformMacOSX
|
||||
lldbPluginPlatformAndroid
|
||||
lldbPluginSymbolFileBreakpad
|
||||
lldbPluginSymbolFileSymtab
|
||||
lldbTarget
|
||||
lldbSymbol
|
||||
@ -27,4 +31,10 @@ add_lldb_unittest(TargetTests
|
||||
Support
|
||||
)
|
||||
|
||||
add_unittest_inputs(TargetTests TestModule.so)
|
||||
set(test_inputs
|
||||
AndroidModule.so
|
||||
AndroidModule.so.sym
|
||||
AndroidModule.unstripped.so
|
||||
TestModule.so
|
||||
)
|
||||
add_unittest_inputs(TargetTests "${test_inputs}")
|
||||
|
13
lldb/unittests/Target/Inputs/AndroidModule.c
Normal file
13
lldb/unittests/Target/Inputs/AndroidModule.c
Normal file
@ -0,0 +1,13 @@
|
||||
// aarch64-linux-android29-clang -shared -Os -glldb -g3 -Wl,--build-id=sha1 \
|
||||
// AndroidModule.c -o AndroidModule.so
|
||||
// dump_syms AndroidModule.so > AndroidModule.so.sym
|
||||
// cp AndroidModule.so AndroidModule.unstripped.so
|
||||
// llvm-strip --strip-unneeded AndroidModule.so
|
||||
|
||||
int boom(void) {
|
||||
return 47;
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden"))) int boom_hidden(void) {
|
||||
return 48;
|
||||
}
|
BIN
lldb/unittests/Target/Inputs/AndroidModule.so
Normal file
BIN
lldb/unittests/Target/Inputs/AndroidModule.so
Normal file
Binary file not shown.
21
lldb/unittests/Target/Inputs/AndroidModule.so.sym
Normal file
21
lldb/unittests/Target/Inputs/AndroidModule.so.sym
Normal file
@ -0,0 +1,21 @@
|
||||
MODULE Linux arm64 38830080A082E5515922C905D23890DA0 AndroidModule.so
|
||||
INFO CODE_ID 8000833882A051E55922C905D23890DABDDEFECC
|
||||
FILE 0 /private/tmp/test/AndroidModule.c
|
||||
FUNC 162c 8 0 boom
|
||||
162c 8 8 0
|
||||
FUNC 1634 8 0 boom_hidden
|
||||
1634 8 12 0
|
||||
PUBLIC 15cc 0 __on_dlclose
|
||||
PUBLIC 15dc 0 __emutls_unregister_key
|
||||
PUBLIC 15e4 0 __on_dlclose_late
|
||||
PUBLIC 15ec 0 __atexit_handler_wrapper
|
||||
PUBLIC 1600 0 atexit
|
||||
PUBLIC 161c 0 pthread_atfork
|
||||
STACK CFI INIT 15cc 10 .cfa: sp 0 + .ra: x30
|
||||
STACK CFI INIT 15dc 8 .cfa: sp 0 + .ra: x30
|
||||
STACK CFI INIT 15e4 8 .cfa: sp 0 + .ra: x30
|
||||
STACK CFI INIT 15ec 14 .cfa: sp 0 + .ra: x30
|
||||
STACK CFI INIT 1600 1c .cfa: sp 0 + .ra: x30
|
||||
STACK CFI INIT 161c 10 .cfa: sp 0 + .ra: x30
|
||||
STACK CFI INIT 162c 8 .cfa: sp 0 + .ra: x30
|
||||
STACK CFI INIT 1634 8 .cfa: sp 0 + .ra: x30
|
BIN
lldb/unittests/Target/Inputs/AndroidModule.unstripped.so
Normal file
BIN
lldb/unittests/Target/Inputs/AndroidModule.unstripped.so
Normal file
Binary file not shown.
640
lldb/unittests/Target/LocateModuleCallbackTest.cpp
Normal file
640
lldb/unittests/Target/LocateModuleCallbackTest.cpp
Normal file
@ -0,0 +1,640 @@
|
||||
//===-- LocateModuleCallbackTest.cpp --------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h"
|
||||
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
|
||||
#include "Plugins/Platform/Android/PlatformAndroid.h"
|
||||
#include "Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h"
|
||||
#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
|
||||
#include "TestingSupport/SubsystemRAII.h"
|
||||
#include "TestingSupport/TestUtilities.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Host/HostInfo.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
using namespace lldb_private::platform_android;
|
||||
using namespace lldb_private::breakpad;
|
||||
using namespace testing;
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr llvm::StringLiteral k_process_plugin("mock-process-plugin");
|
||||
constexpr llvm::StringLiteral k_platform_dir("remote-android");
|
||||
constexpr llvm::StringLiteral k_cache_dir(".cache");
|
||||
constexpr llvm::StringLiteral k_module_file("AndroidModule.so");
|
||||
constexpr llvm::StringLiteral k_symbol_file("AndroidModule.unstripped.so");
|
||||
constexpr llvm::StringLiteral k_breakpad_symbol_file("AndroidModule.so.sym");
|
||||
constexpr llvm::StringLiteral k_arch("aarch64-none-linux");
|
||||
constexpr llvm::StringLiteral
|
||||
k_module_uuid("80008338-82A0-51E5-5922-C905D23890DA-BDDEFECC");
|
||||
constexpr llvm::StringLiteral k_function_symbol("boom");
|
||||
constexpr llvm::StringLiteral k_hidden_function_symbol("boom_hidden");
|
||||
const size_t k_module_size = 3784;
|
||||
|
||||
ModuleSpec GetTestModuleSpec();
|
||||
|
||||
class MockProcess : public Process {
|
||||
public:
|
||||
MockProcess(TargetSP target_sp, ListenerSP listener_sp)
|
||||
: Process(target_sp, listener_sp) {}
|
||||
|
||||
llvm::StringRef GetPluginName() override { return k_process_plugin; };
|
||||
|
||||
bool CanDebug(TargetSP target, bool plugin_specified_by_name) override {
|
||||
return true;
|
||||
}
|
||||
|
||||
Status DoDestroy() override { return Status(); }
|
||||
|
||||
void RefreshStateAfterStop() override {}
|
||||
|
||||
bool DoUpdateThreadList(ThreadList &old_thread_list,
|
||||
ThreadList &new_thread_list) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t DoReadMemory(addr_t vm_addr, void *buf, size_t size,
|
||||
Status &error) override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch,
|
||||
ModuleSpec &module_spec) override {
|
||||
module_spec = GetTestModuleSpec();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
FileSpec GetTestDir() {
|
||||
const auto *info = UnitTest::GetInstance()->current_test_info();
|
||||
FileSpec test_dir = HostInfo::GetProcessTempDir();
|
||||
test_dir.AppendPathComponent(std::string(info->test_case_name()) + "-" +
|
||||
info->name());
|
||||
std::error_code ec = llvm::sys::fs::create_directory(test_dir.GetPath());
|
||||
EXPECT_FALSE(ec);
|
||||
return test_dir;
|
||||
}
|
||||
|
||||
FileSpec GetRemotePath() {
|
||||
FileSpec fs("/", FileSpec::Style::posix);
|
||||
fs.AppendPathComponent("bin");
|
||||
fs.AppendPathComponent(k_module_file);
|
||||
return fs;
|
||||
}
|
||||
|
||||
FileSpec GetUuidView(FileSpec spec) {
|
||||
spec.AppendPathComponent(k_platform_dir);
|
||||
spec.AppendPathComponent(k_cache_dir);
|
||||
spec.AppendPathComponent(k_module_uuid);
|
||||
spec.AppendPathComponent(k_module_file);
|
||||
return spec;
|
||||
}
|
||||
|
||||
void BuildEmptyCacheDir(const FileSpec &test_dir) {
|
||||
FileSpec cache_dir(test_dir);
|
||||
cache_dir.AppendPathComponent(k_platform_dir);
|
||||
cache_dir.AppendPathComponent(k_cache_dir);
|
||||
std::error_code ec = llvm::sys::fs::create_directories(cache_dir.GetPath());
|
||||
EXPECT_FALSE(ec);
|
||||
}
|
||||
|
||||
FileSpec BuildCacheDir(const FileSpec &test_dir) {
|
||||
FileSpec uuid_view = GetUuidView(test_dir);
|
||||
std::error_code ec =
|
||||
llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString());
|
||||
EXPECT_FALSE(ec);
|
||||
ec = llvm::sys::fs::copy_file(GetInputFilePath(k_module_file),
|
||||
uuid_view.GetPath().c_str());
|
||||
EXPECT_FALSE(ec);
|
||||
return uuid_view;
|
||||
}
|
||||
|
||||
FileSpec GetSymFileSpec(const FileSpec &uuid_view) {
|
||||
return FileSpec(uuid_view.GetPath() + ".sym");
|
||||
}
|
||||
|
||||
FileSpec BuildCacheDirWithSymbol(const FileSpec &test_dir) {
|
||||
FileSpec uuid_view = BuildCacheDir(test_dir);
|
||||
std::error_code ec =
|
||||
llvm::sys::fs::copy_file(GetInputFilePath(k_symbol_file),
|
||||
GetSymFileSpec(uuid_view).GetPath().c_str());
|
||||
EXPECT_FALSE(ec);
|
||||
return uuid_view;
|
||||
}
|
||||
|
||||
FileSpec BuildCacheDirWithBreakpadSymbol(const FileSpec &test_dir) {
|
||||
FileSpec uuid_view = BuildCacheDir(test_dir);
|
||||
std::error_code ec =
|
||||
llvm::sys::fs::copy_file(GetInputFilePath(k_breakpad_symbol_file),
|
||||
GetSymFileSpec(uuid_view).GetPath().c_str());
|
||||
EXPECT_FALSE(ec);
|
||||
return uuid_view;
|
||||
}
|
||||
|
||||
ModuleSpec GetTestModuleSpec() {
|
||||
ModuleSpec module_spec(GetRemotePath(), ArchSpec(k_arch));
|
||||
module_spec.GetUUID().SetFromStringRef(k_module_uuid);
|
||||
module_spec.SetObjectSize(k_module_size);
|
||||
return module_spec;
|
||||
}
|
||||
|
||||
void CheckModule(const ModuleSP &module_sp) {
|
||||
ASSERT_TRUE(module_sp);
|
||||
ASSERT_EQ(module_sp->GetUUID().GetAsString(), k_module_uuid);
|
||||
ASSERT_EQ(module_sp->GetObjectOffset(), 0U);
|
||||
ASSERT_EQ(module_sp->GetPlatformFileSpec(), GetRemotePath());
|
||||
}
|
||||
|
||||
SymbolContextList FindFunctions(const ModuleSP &module_sp,
|
||||
const llvm::StringRef &name) {
|
||||
SymbolContextList sc_list;
|
||||
ModuleFunctionSearchOptions function_options;
|
||||
function_options.include_symbols = true;
|
||||
function_options.include_inlines = true;
|
||||
FunctionNameType type = static_cast<FunctionNameType>(eSymbolTypeCode);
|
||||
module_sp->FindFunctions(ConstString(name), CompilerDeclContext(), type,
|
||||
function_options, sc_list);
|
||||
return sc_list;
|
||||
}
|
||||
|
||||
void CheckStrippedSymbol(const ModuleSP &module_sp) {
|
||||
SymbolContextList sc_list = FindFunctions(module_sp, k_function_symbol);
|
||||
EXPECT_EQ(1U, sc_list.GetSize());
|
||||
|
||||
sc_list = FindFunctions(module_sp, k_hidden_function_symbol);
|
||||
EXPECT_EQ(0U, sc_list.GetSize());
|
||||
}
|
||||
|
||||
void CheckUnstrippedSymbol(const ModuleSP &module_sp) {
|
||||
SymbolContextList sc_list = FindFunctions(module_sp, k_function_symbol);
|
||||
EXPECT_EQ(1U, sc_list.GetSize());
|
||||
|
||||
sc_list = FindFunctions(module_sp, k_hidden_function_symbol);
|
||||
EXPECT_EQ(1U, sc_list.GetSize());
|
||||
}
|
||||
|
||||
ProcessSP MockProcessCreateInstance(TargetSP target_sp, ListenerSP listener_sp,
|
||||
const FileSpec *crash_file_path,
|
||||
bool can_connect) {
|
||||
return std::make_shared<MockProcess>(target_sp, listener_sp);
|
||||
}
|
||||
|
||||
class LocateModuleCallbackTest : public testing::Test {
|
||||
SubsystemRAII<FileSystem, HostInfo, ObjectFileBreakpad, ObjectFileELF,
|
||||
PlatformAndroid, SymbolFileBreakpad, SymbolFileSymtab>
|
||||
subsystems;
|
||||
|
||||
public:
|
||||
void SetUp() override {
|
||||
m_test_dir = GetTestDir();
|
||||
|
||||
// Set module cache directory for PlatformAndroid.
|
||||
PlatformAndroid::GetGlobalPlatformProperties().SetModuleCacheDirectory(
|
||||
m_test_dir);
|
||||
|
||||
// Create Debugger.
|
||||
m_debugger_sp = Debugger::CreateInstance();
|
||||
EXPECT_TRUE(m_debugger_sp);
|
||||
|
||||
// Create PlatformAndroid.
|
||||
ArchSpec arch(k_arch);
|
||||
m_platform_sp = PlatformAndroid::CreateInstance(true, &arch);
|
||||
EXPECT_TRUE(m_platform_sp);
|
||||
|
||||
// Create Target.
|
||||
m_debugger_sp->GetTargetList().CreateTarget(*m_debugger_sp, "", arch,
|
||||
eLoadDependentsNo,
|
||||
m_platform_sp, m_target_sp);
|
||||
EXPECT_TRUE(m_target_sp);
|
||||
|
||||
// Create MockProcess.
|
||||
PluginManager::RegisterPlugin(k_process_plugin, "",
|
||||
MockProcessCreateInstance);
|
||||
m_process_sp =
|
||||
m_target_sp->CreateProcess(Listener::MakeListener("test-listener"),
|
||||
k_process_plugin, /*crash_file=*/nullptr,
|
||||
/*can_connect=*/true);
|
||||
EXPECT_TRUE(m_process_sp);
|
||||
|
||||
m_module_spec = GetTestModuleSpec();
|
||||
}
|
||||
|
||||
void CheckNoCallback() {
|
||||
EXPECT_FALSE(m_platform_sp->GetLocateModuleCallback());
|
||||
EXPECT_EQ(m_callback_call_count, 0);
|
||||
}
|
||||
|
||||
void CheckCallbackArgs(const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
EXPECT_TRUE(m_module_spec.Matches(module_spec,
|
||||
/*exact_arch_match=*/true));
|
||||
EXPECT_FALSE(module_file_spec);
|
||||
EXPECT_FALSE(symbol_file_spec);
|
||||
|
||||
EXPECT_EQ(m_callback_call_count, 0);
|
||||
m_callback_call_count++;
|
||||
}
|
||||
|
||||
protected:
|
||||
FileSpec m_test_dir;
|
||||
DebuggerSP m_debugger_sp;
|
||||
PlatformSP m_platform_sp;
|
||||
TargetSP m_target_sp;
|
||||
ProcessSP m_process_sp;
|
||||
ModuleSpec m_module_spec;
|
||||
int m_callback_call_count = 0;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_F(LocateModuleCallbackTest, GetOrCreateModuleWithCachedModule) {
|
||||
// The module file is cached, and the locate module callback is not set.
|
||||
// GetOrCreateModule should succeed to return the module from the cache.
|
||||
FileSpec uuid_view = BuildCacheDir(m_test_dir);
|
||||
|
||||
CheckNoCallback();
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
CheckModule(module_sp);
|
||||
ASSERT_EQ(module_sp->GetFileSpec(), uuid_view);
|
||||
ASSERT_FALSE(module_sp->GetSymbolFileFileSpec());
|
||||
CheckStrippedSymbol(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest, GetOrCreateModuleWithCachedModuleAndSymbol) {
|
||||
// The module and symbol files are cached, and the locate module callback is
|
||||
// not set. GetOrCreateModule should succeed to return the module from the
|
||||
// cache with the symbol.
|
||||
FileSpec uuid_view = BuildCacheDirWithSymbol(m_test_dir);
|
||||
|
||||
CheckNoCallback();
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
CheckModule(module_sp);
|
||||
ASSERT_EQ(module_sp->GetFileSpec(), uuid_view);
|
||||
ASSERT_EQ(module_sp->GetSymbolFileFileSpec(), GetSymFileSpec(uuid_view));
|
||||
CheckUnstrippedSymbol(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest,
|
||||
GetOrCreateModuleWithCachedModuleAndBreakpadSymbol) {
|
||||
// The module file and breakpad symbol file are cached, and the locate module
|
||||
// callback is not set. GetOrCreateModule should succeed to return the module
|
||||
// from the cache with the symbol.
|
||||
FileSpec uuid_view = BuildCacheDirWithBreakpadSymbol(m_test_dir);
|
||||
|
||||
CheckNoCallback();
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
CheckModule(module_sp);
|
||||
ASSERT_EQ(module_sp->GetFileSpec(), uuid_view);
|
||||
ASSERT_EQ(module_sp->GetSymbolFileFileSpec(), GetSymFileSpec(uuid_view));
|
||||
CheckUnstrippedSymbol(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest, GetOrCreateModuleFailure) {
|
||||
// The cache dir is empty, and the locate module callback is not set.
|
||||
// GetOrCreateModule should fail because PlatformAndroid tries to download the
|
||||
// module and fails.
|
||||
BuildEmptyCacheDir(m_test_dir);
|
||||
|
||||
CheckNoCallback();
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
ASSERT_FALSE(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest, GetOrCreateModuleCallbackFailureNoCache) {
|
||||
// The cache dir is empty, also the locate module callback fails for some
|
||||
// reason. GetOrCreateModule should fail because PlatformAndroid tries to
|
||||
// download the module and fails.
|
||||
BuildEmptyCacheDir(m_test_dir);
|
||||
|
||||
m_platform_sp->SetLocateModuleCallback([this](const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
CheckCallbackArgs(module_spec, module_file_spec, symbol_file_spec);
|
||||
return Status("The locate module callback failed");
|
||||
});
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
ASSERT_FALSE(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest, GetOrCreateModuleCallbackFailureCached) {
|
||||
// The module file is cached, so GetOrCreateModule should succeed to return
|
||||
// the module from the cache even though the locate module callback fails for
|
||||
// some reason.
|
||||
FileSpec uuid_view = BuildCacheDir(m_test_dir);
|
||||
|
||||
m_platform_sp->SetLocateModuleCallback([this](const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
CheckCallbackArgs(module_spec, module_file_spec, symbol_file_spec);
|
||||
return Status("The locate module callback failed");
|
||||
});
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
CheckModule(module_sp);
|
||||
ASSERT_EQ(module_sp->GetFileSpec(), uuid_view);
|
||||
ASSERT_FALSE(module_sp->GetSymbolFileFileSpec());
|
||||
CheckStrippedSymbol(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest, GetOrCreateModuleCallbackNoFiles) {
|
||||
// The module file is cached, so GetOrCreateModule should succeed to return
|
||||
// the module from the cache even though the locate module callback returns
|
||||
// no files.
|
||||
FileSpec uuid_view = BuildCacheDir(m_test_dir);
|
||||
|
||||
m_platform_sp->SetLocateModuleCallback([this](const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
CheckCallbackArgs(module_spec, module_file_spec, symbol_file_spec);
|
||||
// The locate module callback succeeds but it does not set
|
||||
// module_file_spec nor symbol_file_spec.
|
||||
return Status();
|
||||
});
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
CheckModule(module_sp);
|
||||
ASSERT_EQ(module_sp->GetFileSpec(), uuid_view);
|
||||
ASSERT_FALSE(module_sp->GetSymbolFileFileSpec());
|
||||
CheckStrippedSymbol(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest, GetOrCreateModuleCallbackNonExistentModule) {
|
||||
// The module file is cached, so GetOrCreateModule should succeed to return
|
||||
// the module from the cache even though the locate module callback returns
|
||||
// non-existent module file.
|
||||
FileSpec uuid_view = BuildCacheDir(m_test_dir);
|
||||
|
||||
m_platform_sp->SetLocateModuleCallback([this](const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
CheckCallbackArgs(module_spec, module_file_spec, symbol_file_spec);
|
||||
module_file_spec.SetPath("/this path does not exist");
|
||||
return Status();
|
||||
});
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
CheckModule(module_sp);
|
||||
ASSERT_EQ(module_sp->GetFileSpec(), uuid_view);
|
||||
ASSERT_FALSE(module_sp->GetSymbolFileFileSpec());
|
||||
CheckStrippedSymbol(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest, GetOrCreateModuleCallbackNonExistentSymbol) {
|
||||
// The module file is cached, so GetOrCreateModule should succeed to return
|
||||
// the module from the cache even though the locate module callback returns
|
||||
// non-existent symbol file.
|
||||
FileSpec uuid_view = BuildCacheDir(m_test_dir);
|
||||
|
||||
m_platform_sp->SetLocateModuleCallback([this](const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
CheckCallbackArgs(module_spec, module_file_spec, symbol_file_spec);
|
||||
// The locate module callback returns a right module file.
|
||||
module_file_spec.SetPath(GetInputFilePath(k_module_file));
|
||||
// But it returns non-existent symbols file.
|
||||
symbol_file_spec.SetPath("/this path does not exist");
|
||||
return Status();
|
||||
});
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
CheckModule(module_sp);
|
||||
ASSERT_EQ(module_sp->GetFileSpec(), uuid_view);
|
||||
ASSERT_TRUE(module_sp->GetSymbolFileFileSpec().GetPath().empty());
|
||||
CheckStrippedSymbol(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest, GetOrCreateModuleCallbackSuccessWithModule) {
|
||||
// The locate module callback returns a module file, GetOrCreateModule should
|
||||
// succeed to return the module from the Inputs directory.
|
||||
BuildEmptyCacheDir(m_test_dir);
|
||||
|
||||
m_platform_sp->SetLocateModuleCallback([this](const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
CheckCallbackArgs(module_spec, module_file_spec, symbol_file_spec);
|
||||
module_file_spec.SetPath(GetInputFilePath(k_module_file));
|
||||
return Status();
|
||||
});
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
CheckModule(module_sp);
|
||||
ASSERT_EQ(module_sp->GetFileSpec(),
|
||||
FileSpec(GetInputFilePath(k_module_file)));
|
||||
ASSERT_FALSE(module_sp->GetSymbolFileFileSpec());
|
||||
CheckStrippedSymbol(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest,
|
||||
GetOrCreateModuleCallbackSuccessWithSymbolAsModule) {
|
||||
// The locate module callback returns the symbol file as a module file. It
|
||||
// should work since the sections and UUID of the symbol file are the exact
|
||||
// same with the module file, GetOrCreateModule should succeed to return the
|
||||
// module with the symbol file from Inputs directory.
|
||||
BuildEmptyCacheDir(m_test_dir);
|
||||
|
||||
m_platform_sp->SetLocateModuleCallback([this](const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
CheckCallbackArgs(module_spec, module_file_spec, symbol_file_spec);
|
||||
module_file_spec.SetPath(GetInputFilePath(k_symbol_file));
|
||||
return Status();
|
||||
});
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
CheckModule(module_sp);
|
||||
ASSERT_EQ(module_sp->GetFileSpec(),
|
||||
FileSpec(GetInputFilePath(k_symbol_file)));
|
||||
ASSERT_FALSE(module_sp->GetSymbolFileFileSpec());
|
||||
CheckUnstrippedSymbol(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest,
|
||||
GetOrCreateModuleCallbackSuccessWithSymbolAsModuleAndSymbol) {
|
||||
// The locate module callback returns a symbol file as both a module file and
|
||||
// a symbol file. It should work since the sections and UUID of the symbol
|
||||
// file are the exact same with the module file, GetOrCreateModule should
|
||||
// succeed to return the module with the symbol file from Inputs directory.
|
||||
BuildEmptyCacheDir(m_test_dir);
|
||||
|
||||
m_platform_sp->SetLocateModuleCallback([this](const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
CheckCallbackArgs(module_spec, module_file_spec, symbol_file_spec);
|
||||
module_file_spec.SetPath(GetInputFilePath(k_symbol_file));
|
||||
symbol_file_spec.SetPath(GetInputFilePath(k_symbol_file));
|
||||
return Status();
|
||||
});
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
CheckModule(module_sp);
|
||||
ASSERT_EQ(module_sp->GetFileSpec(),
|
||||
FileSpec(GetInputFilePath(k_symbol_file)));
|
||||
ASSERT_EQ(module_sp->GetSymbolFileFileSpec(),
|
||||
FileSpec(GetInputFilePath(k_symbol_file)));
|
||||
CheckUnstrippedSymbol(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest,
|
||||
GetOrCreateModuleCallbackSuccessWithModuleAndSymbol) {
|
||||
// The locate module callback returns a module file and a symbol file,
|
||||
// GetOrCreateModule should succeed to return the module from Inputs
|
||||
// directory, along with the symbol file.
|
||||
BuildEmptyCacheDir(m_test_dir);
|
||||
|
||||
m_platform_sp->SetLocateModuleCallback([this](const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
CheckCallbackArgs(module_spec, module_file_spec, symbol_file_spec);
|
||||
module_file_spec.SetPath(GetInputFilePath(k_module_file));
|
||||
symbol_file_spec.SetPath(GetInputFilePath(k_symbol_file));
|
||||
return Status();
|
||||
});
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
CheckModule(module_sp);
|
||||
ASSERT_EQ(module_sp->GetFileSpec(),
|
||||
FileSpec(GetInputFilePath(k_module_file)));
|
||||
ASSERT_EQ(module_sp->GetSymbolFileFileSpec(),
|
||||
FileSpec(GetInputFilePath(k_symbol_file)));
|
||||
CheckUnstrippedSymbol(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest,
|
||||
GetOrCreateModuleCallbackSuccessWithModuleAndBreakpadSymbol) {
|
||||
// The locate module callback returns a module file and a breakpad symbol
|
||||
// file, GetOrCreateModule should succeed to return the module with the symbol
|
||||
// file from Inputs directory.
|
||||
BuildEmptyCacheDir(m_test_dir);
|
||||
|
||||
m_platform_sp->SetLocateModuleCallback([this](const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
CheckCallbackArgs(module_spec, module_file_spec, symbol_file_spec);
|
||||
module_file_spec.SetPath(GetInputFilePath(k_module_file));
|
||||
symbol_file_spec.SetPath(GetInputFilePath(k_breakpad_symbol_file));
|
||||
return Status();
|
||||
});
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
CheckModule(module_sp);
|
||||
ASSERT_EQ(module_sp->GetFileSpec(),
|
||||
FileSpec(GetInputFilePath(k_module_file)));
|
||||
ASSERT_EQ(module_sp->GetSymbolFileFileSpec(),
|
||||
FileSpec(GetInputFilePath(k_breakpad_symbol_file)));
|
||||
CheckUnstrippedSymbol(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest,
|
||||
GetOrCreateModuleCallbackSuccessWithOnlySymbol) {
|
||||
// The get callback returns only a symbol file, and the module is cached,
|
||||
// GetOrCreateModule should succeed to return the module from the cache
|
||||
// along with the symbol file from the Inputs directory.
|
||||
FileSpec uuid_view = BuildCacheDir(m_test_dir);
|
||||
|
||||
m_platform_sp->SetLocateModuleCallback([this](const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
CheckCallbackArgs(module_spec, module_file_spec, symbol_file_spec);
|
||||
symbol_file_spec.SetPath(GetInputFilePath(k_symbol_file));
|
||||
return Status();
|
||||
});
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
CheckModule(module_sp);
|
||||
ASSERT_EQ(module_sp->GetFileSpec(), uuid_view);
|
||||
ASSERT_EQ(module_sp->GetSymbolFileFileSpec(),
|
||||
FileSpec(GetInputFilePath(k_symbol_file)));
|
||||
CheckUnstrippedSymbol(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest,
|
||||
GetOrCreateModuleCallbackSuccessWithOnlyBreakpadSymbol) {
|
||||
// The get callback returns only a breakpad symbol file, and the module is
|
||||
// cached, GetOrCreateModule should succeed to return the module from the
|
||||
// cache along with the symbol file from the Inputs directory.
|
||||
FileSpec uuid_view = BuildCacheDir(m_test_dir);
|
||||
|
||||
m_platform_sp->SetLocateModuleCallback([this](const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
CheckCallbackArgs(module_spec, module_file_spec, symbol_file_spec);
|
||||
symbol_file_spec.SetPath(GetInputFilePath(k_breakpad_symbol_file));
|
||||
return Status();
|
||||
});
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
CheckModule(module_sp);
|
||||
ASSERT_EQ(module_sp->GetFileSpec(), uuid_view);
|
||||
ASSERT_EQ(module_sp->GetSymbolFileFileSpec(),
|
||||
FileSpec(GetInputFilePath(k_breakpad_symbol_file)));
|
||||
CheckUnstrippedSymbol(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest,
|
||||
GetOrCreateModuleNoCacheWithCallbackOnlySymbol) {
|
||||
// The get callback returns only a symbol file, but the module is not
|
||||
// cached, GetOrCreateModule should fail because of the missing module.
|
||||
BuildEmptyCacheDir(m_test_dir);
|
||||
|
||||
m_platform_sp->SetLocateModuleCallback([this](const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
CheckCallbackArgs(module_spec, module_file_spec, symbol_file_spec);
|
||||
symbol_file_spec.SetPath(GetInputFilePath(k_symbol_file));
|
||||
return Status();
|
||||
});
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
ASSERT_FALSE(module_sp);
|
||||
}
|
||||
|
||||
TEST_F(LocateModuleCallbackTest,
|
||||
GetOrCreateModuleNoCacheWithCallbackOnlyBreakpadSymbol) {
|
||||
// The get callback returns only a breakpad symbol file, but the module is not
|
||||
// cached, GetOrCreateModule should fail because of the missing module.
|
||||
BuildEmptyCacheDir(m_test_dir);
|
||||
|
||||
m_platform_sp->SetLocateModuleCallback([this](const ModuleSpec &module_spec,
|
||||
FileSpec &module_file_spec,
|
||||
FileSpec &symbol_file_spec) {
|
||||
CheckCallbackArgs(module_spec, module_file_spec, symbol_file_spec);
|
||||
symbol_file_spec.SetPath(GetInputFilePath(k_breakpad_symbol_file));
|
||||
return Status();
|
||||
});
|
||||
|
||||
ModuleSP module_sp =
|
||||
m_target_sp->GetOrCreateModule(m_module_spec, /*notify=*/false);
|
||||
ASSERT_FALSE(module_sp);
|
||||
}
|
Loading…
Reference in New Issue
Block a user