mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
linux: Refactor test modules
This patch moves LoadModule() to it's own file from process_reader_linux_test.cc so that it may be used in other tests that interact with loaded modules. Change-Id: Ie4f7932d65710fc3e20b6e2488e497c5aab27cdd Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2569882 Reviewed-by: Mark Mentovai <mark@chromium.org> Commit-Queue: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
parent
121d92ca3f
commit
6c270cf239
@ -368,6 +368,8 @@ source_set("snapshot_test") {
|
||||
"linux/exception_snapshot_linux_test.cc",
|
||||
"linux/process_reader_linux_test.cc",
|
||||
"linux/system_snapshot_linux_test.cc",
|
||||
"linux/test_modules.cc",
|
||||
"linux/test_modules.h",
|
||||
"sanitized/process_snapshot_sanitized_test.cc",
|
||||
"sanitized/sanitization_information_test.cc",
|
||||
]
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "build/build_config.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "snapshot/linux/test_modules.h"
|
||||
#include "test/errors.h"
|
||||
#include "test/linux/fake_ptrace_connection.h"
|
||||
#include "test/linux/get_tls.h"
|
||||
@ -541,218 +542,6 @@ void ExpectModulesFromSelf(
|
||||
#endif // !OS_ANDROID || !ARCH_CPU_ARMEL || __ANDROID_API__ >= 21
|
||||
}
|
||||
|
||||
bool WriteTestModule(const base::FilePath& module_path,
|
||||
const std::string& soname) {
|
||||
#if defined(ARCH_CPU_64_BITS)
|
||||
using Ehdr = Elf64_Ehdr;
|
||||
using Phdr = Elf64_Phdr;
|
||||
using Shdr = Elf64_Shdr;
|
||||
using Dyn = Elf64_Dyn;
|
||||
using Sym = Elf64_Sym;
|
||||
unsigned char elf_class = ELFCLASS64;
|
||||
#else
|
||||
using Ehdr = Elf32_Ehdr;
|
||||
using Phdr = Elf32_Phdr;
|
||||
using Shdr = Elf32_Shdr;
|
||||
using Dyn = Elf32_Dyn;
|
||||
using Sym = Elf32_Sym;
|
||||
unsigned char elf_class = ELFCLASS32;
|
||||
#endif
|
||||
|
||||
struct {
|
||||
Ehdr ehdr;
|
||||
struct {
|
||||
Phdr load1;
|
||||
Phdr load2;
|
||||
Phdr dynamic;
|
||||
} phdr_table;
|
||||
struct {
|
||||
Dyn hash;
|
||||
Dyn strtab;
|
||||
Dyn symtab;
|
||||
Dyn strsz;
|
||||
Dyn syment;
|
||||
Dyn soname;
|
||||
Dyn null;
|
||||
} dynamic_array;
|
||||
struct {
|
||||
Elf32_Word nbucket;
|
||||
Elf32_Word nchain;
|
||||
Elf32_Word bucket;
|
||||
Elf32_Word chain;
|
||||
} hash_table;
|
||||
char string_table[32];
|
||||
struct {
|
||||
} section_header_string_table;
|
||||
struct {
|
||||
Sym und_symbol;
|
||||
} symbol_table;
|
||||
struct {
|
||||
Shdr null;
|
||||
Shdr dynamic;
|
||||
Shdr string_table;
|
||||
Shdr section_header_string_table;
|
||||
} shdr_table;
|
||||
} module = {};
|
||||
|
||||
module.ehdr.e_ident[EI_MAG0] = ELFMAG0;
|
||||
module.ehdr.e_ident[EI_MAG1] = ELFMAG1;
|
||||
module.ehdr.e_ident[EI_MAG2] = ELFMAG2;
|
||||
module.ehdr.e_ident[EI_MAG3] = ELFMAG3;
|
||||
|
||||
module.ehdr.e_ident[EI_CLASS] = elf_class;
|
||||
|
||||
#if defined(ARCH_CPU_LITTLE_ENDIAN)
|
||||
module.ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
|
||||
#else
|
||||
module.ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
|
||||
#endif // ARCH_CPU_LITTLE_ENDIAN
|
||||
|
||||
module.ehdr.e_ident[EI_VERSION] = EV_CURRENT;
|
||||
|
||||
module.ehdr.e_type = ET_DYN;
|
||||
|
||||
#if defined(ARCH_CPU_X86)
|
||||
module.ehdr.e_machine = EM_386;
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
module.ehdr.e_machine = EM_X86_64;
|
||||
#elif defined(ARCH_CPU_ARMEL)
|
||||
module.ehdr.e_machine = EM_ARM;
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
module.ehdr.e_machine = EM_AARCH64;
|
||||
#elif defined(ARCH_CPU_MIPSEL) || defined(ARCH_CPU_MIPS64EL)
|
||||
module.ehdr.e_machine = EM_MIPS;
|
||||
#endif
|
||||
|
||||
module.ehdr.e_version = EV_CURRENT;
|
||||
module.ehdr.e_ehsize = sizeof(module.ehdr);
|
||||
|
||||
module.ehdr.e_phoff = offsetof(decltype(module), phdr_table);
|
||||
module.ehdr.e_phnum = sizeof(module.phdr_table) / sizeof(Phdr);
|
||||
module.ehdr.e_phentsize = sizeof(Phdr);
|
||||
|
||||
module.ehdr.e_shoff = offsetof(decltype(module), shdr_table);
|
||||
module.ehdr.e_shentsize = sizeof(Shdr);
|
||||
module.ehdr.e_shnum = sizeof(module.shdr_table) / sizeof(Shdr);
|
||||
module.ehdr.e_shstrndx =
|
||||
offsetof(decltype(module.shdr_table), section_header_string_table) /
|
||||
sizeof(Shdr);
|
||||
|
||||
constexpr size_t load2_vaddr = 0x200000;
|
||||
|
||||
module.phdr_table.load1.p_type = PT_LOAD;
|
||||
module.phdr_table.load1.p_offset = 0;
|
||||
module.phdr_table.load1.p_vaddr = 0;
|
||||
module.phdr_table.load1.p_filesz = offsetof(decltype(module), shdr_table);
|
||||
module.phdr_table.load1.p_memsz = offsetof(decltype(module), shdr_table);
|
||||
module.phdr_table.load1.p_flags = PF_R;
|
||||
module.phdr_table.load1.p_align = load2_vaddr;
|
||||
|
||||
module.phdr_table.load2.p_type = PT_LOAD;
|
||||
module.phdr_table.load2.p_offset = 0;
|
||||
module.phdr_table.load2.p_vaddr = load2_vaddr;
|
||||
module.phdr_table.load2.p_filesz = offsetof(decltype(module), shdr_table);
|
||||
module.phdr_table.load2.p_memsz = offsetof(decltype(module), shdr_table);
|
||||
module.phdr_table.load2.p_flags = PF_R | PF_W;
|
||||
module.phdr_table.load2.p_align = load2_vaddr;
|
||||
|
||||
module.phdr_table.dynamic.p_type = PT_DYNAMIC;
|
||||
module.phdr_table.dynamic.p_offset =
|
||||
offsetof(decltype(module), dynamic_array);
|
||||
module.phdr_table.dynamic.p_vaddr =
|
||||
load2_vaddr + module.phdr_table.dynamic.p_offset;
|
||||
module.phdr_table.dynamic.p_filesz = sizeof(module.dynamic_array);
|
||||
module.phdr_table.dynamic.p_memsz = sizeof(module.dynamic_array);
|
||||
module.phdr_table.dynamic.p_flags = PF_R | PF_W;
|
||||
module.phdr_table.dynamic.p_align = 8;
|
||||
|
||||
module.dynamic_array.hash.d_tag = DT_HASH;
|
||||
module.dynamic_array.hash.d_un.d_ptr = offsetof(decltype(module), hash_table);
|
||||
module.dynamic_array.strtab.d_tag = DT_STRTAB;
|
||||
module.dynamic_array.strtab.d_un.d_ptr =
|
||||
offsetof(decltype(module), string_table);
|
||||
module.dynamic_array.symtab.d_tag = DT_SYMTAB;
|
||||
module.dynamic_array.symtab.d_un.d_ptr =
|
||||
offsetof(decltype(module), symbol_table);
|
||||
module.dynamic_array.strsz.d_tag = DT_STRSZ;
|
||||
module.dynamic_array.strsz.d_un.d_val = sizeof(module.string_table);
|
||||
module.dynamic_array.syment.d_tag = DT_SYMENT;
|
||||
module.dynamic_array.syment.d_un.d_val = sizeof(Sym);
|
||||
constexpr size_t kSonameOffset = 1;
|
||||
module.dynamic_array.soname.d_tag = DT_SONAME;
|
||||
module.dynamic_array.soname.d_un.d_val = kSonameOffset;
|
||||
|
||||
module.dynamic_array.null.d_tag = DT_NULL;
|
||||
|
||||
module.hash_table.nbucket = 1;
|
||||
module.hash_table.nchain = 1;
|
||||
module.hash_table.bucket = 0;
|
||||
module.hash_table.chain = 0;
|
||||
|
||||
CHECK_GE(sizeof(module.string_table), soname.size() + 2);
|
||||
module.string_table[0] = '\0';
|
||||
memcpy(&module.string_table[kSonameOffset], soname.c_str(), soname.size());
|
||||
|
||||
module.shdr_table.null.sh_type = SHT_NULL;
|
||||
|
||||
module.shdr_table.dynamic.sh_name = 0;
|
||||
module.shdr_table.dynamic.sh_type = SHT_DYNAMIC;
|
||||
module.shdr_table.dynamic.sh_flags = SHF_WRITE | SHF_ALLOC;
|
||||
module.shdr_table.dynamic.sh_addr = module.phdr_table.dynamic.p_vaddr;
|
||||
module.shdr_table.dynamic.sh_offset = module.phdr_table.dynamic.p_offset;
|
||||
module.shdr_table.dynamic.sh_size = module.phdr_table.dynamic.p_filesz;
|
||||
module.shdr_table.dynamic.sh_link =
|
||||
offsetof(decltype(module.shdr_table), string_table) / sizeof(Shdr);
|
||||
|
||||
module.shdr_table.string_table.sh_name = 0;
|
||||
module.shdr_table.string_table.sh_type = SHT_STRTAB;
|
||||
module.shdr_table.string_table.sh_offset =
|
||||
offsetof(decltype(module), string_table);
|
||||
module.shdr_table.string_table.sh_size = sizeof(module.string_table);
|
||||
|
||||
module.shdr_table.section_header_string_table.sh_name = 0;
|
||||
module.shdr_table.section_header_string_table.sh_type = SHT_STRTAB;
|
||||
module.shdr_table.section_header_string_table.sh_offset =
|
||||
offsetof(decltype(module), section_header_string_table);
|
||||
module.shdr_table.section_header_string_table.sh_size =
|
||||
sizeof(module.section_header_string_table);
|
||||
|
||||
FileWriter writer;
|
||||
if (!writer.Open(module_path,
|
||||
FileWriteMode::kCreateOrFail,
|
||||
FilePermissions::kWorldReadable)) {
|
||||
ADD_FAILURE();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!writer.Write(&module, sizeof(module))) {
|
||||
ADD_FAILURE();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopedModuleHandle LoadTestModule(const std::string& module_name,
|
||||
const std::string& module_soname) {
|
||||
base::FilePath module_path(
|
||||
TestPaths::Executable().DirName().Append(module_name));
|
||||
|
||||
if (!WriteTestModule(module_path, module_soname)) {
|
||||
return ScopedModuleHandle(nullptr);
|
||||
}
|
||||
EXPECT_TRUE(IsRegularFile(module_path));
|
||||
|
||||
ScopedModuleHandle handle(
|
||||
dlopen(module_path.value().c_str(), RTLD_LAZY | RTLD_LOCAL));
|
||||
EXPECT_TRUE(handle.valid())
|
||||
<< "dlopen: " << module_path.value() << " " << dlerror();
|
||||
|
||||
EXPECT_TRUE(LoggingRemoveFile(module_path));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void ExpectTestModule(ProcessReaderLinux* reader,
|
||||
const std::string& module_name) {
|
||||
for (const auto& module : reader->Modules()) {
|
||||
|
249
snapshot/linux/test_modules.cc
Normal file
249
snapshot/linux/test_modules.cc
Normal file
@ -0,0 +1,249 @@
|
||||
// Copyright 2020 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "snapshot/linux/test_modules.h"
|
||||
|
||||
#include <elf.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "base/check_op.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "build/build_config.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "test/test_paths.h"
|
||||
#include "util/file/filesystem.h"
|
||||
#include "util/file/file_writer.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
bool WriteTestModule(const base::FilePath& module_path,
|
||||
const std::string& soname) {
|
||||
#if defined(ARCH_CPU_64_BITS)
|
||||
using Ehdr = Elf64_Ehdr;
|
||||
using Phdr = Elf64_Phdr;
|
||||
using Shdr = Elf64_Shdr;
|
||||
using Dyn = Elf64_Dyn;
|
||||
using Sym = Elf64_Sym;
|
||||
unsigned char elf_class = ELFCLASS64;
|
||||
#else
|
||||
using Ehdr = Elf32_Ehdr;
|
||||
using Phdr = Elf32_Phdr;
|
||||
using Shdr = Elf32_Shdr;
|
||||
using Dyn = Elf32_Dyn;
|
||||
using Sym = Elf32_Sym;
|
||||
unsigned char elf_class = ELFCLASS32;
|
||||
#endif
|
||||
|
||||
struct {
|
||||
Ehdr ehdr;
|
||||
struct {
|
||||
Phdr load1;
|
||||
Phdr load2;
|
||||
Phdr dynamic;
|
||||
} phdr_table;
|
||||
struct {
|
||||
Dyn hash;
|
||||
Dyn strtab;
|
||||
Dyn symtab;
|
||||
Dyn strsz;
|
||||
Dyn syment;
|
||||
Dyn soname;
|
||||
Dyn null;
|
||||
} dynamic_array;
|
||||
struct {
|
||||
Elf32_Word nbucket;
|
||||
Elf32_Word nchain;
|
||||
Elf32_Word bucket;
|
||||
Elf32_Word chain;
|
||||
} hash_table;
|
||||
char string_table[32];
|
||||
struct {
|
||||
} section_header_string_table;
|
||||
struct {
|
||||
Sym und_symbol;
|
||||
} symbol_table;
|
||||
struct {
|
||||
Shdr null;
|
||||
Shdr dynamic;
|
||||
Shdr string_table;
|
||||
Shdr section_header_string_table;
|
||||
} shdr_table;
|
||||
} module = {};
|
||||
|
||||
module.ehdr.e_ident[EI_MAG0] = ELFMAG0;
|
||||
module.ehdr.e_ident[EI_MAG1] = ELFMAG1;
|
||||
module.ehdr.e_ident[EI_MAG2] = ELFMAG2;
|
||||
module.ehdr.e_ident[EI_MAG3] = ELFMAG3;
|
||||
|
||||
module.ehdr.e_ident[EI_CLASS] = elf_class;
|
||||
|
||||
#if defined(ARCH_CPU_LITTLE_ENDIAN)
|
||||
module.ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
|
||||
#else
|
||||
module.ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
|
||||
#endif // ARCH_CPU_LITTLE_ENDIAN
|
||||
|
||||
module.ehdr.e_ident[EI_VERSION] = EV_CURRENT;
|
||||
|
||||
module.ehdr.e_type = ET_DYN;
|
||||
|
||||
#if defined(ARCH_CPU_X86)
|
||||
module.ehdr.e_machine = EM_386;
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
module.ehdr.e_machine = EM_X86_64;
|
||||
#elif defined(ARCH_CPU_ARMEL)
|
||||
module.ehdr.e_machine = EM_ARM;
|
||||
#elif defined(ARCH_CPU_ARM64)
|
||||
module.ehdr.e_machine = EM_AARCH64;
|
||||
#elif defined(ARCH_CPU_MIPSEL) || defined(ARCH_CPU_MIPS64EL)
|
||||
module.ehdr.e_machine = EM_MIPS;
|
||||
#endif
|
||||
|
||||
module.ehdr.e_version = EV_CURRENT;
|
||||
module.ehdr.e_ehsize = sizeof(module.ehdr);
|
||||
|
||||
module.ehdr.e_phoff = offsetof(decltype(module), phdr_table);
|
||||
module.ehdr.e_phnum = sizeof(module.phdr_table) / sizeof(Phdr);
|
||||
module.ehdr.e_phentsize = sizeof(Phdr);
|
||||
|
||||
module.ehdr.e_shoff = offsetof(decltype(module), shdr_table);
|
||||
module.ehdr.e_shentsize = sizeof(Shdr);
|
||||
module.ehdr.e_shnum = sizeof(module.shdr_table) / sizeof(Shdr);
|
||||
module.ehdr.e_shstrndx =
|
||||
offsetof(decltype(module.shdr_table), section_header_string_table) /
|
||||
sizeof(Shdr);
|
||||
|
||||
constexpr size_t load2_vaddr = 0x200000;
|
||||
|
||||
module.phdr_table.load1.p_type = PT_LOAD;
|
||||
module.phdr_table.load1.p_offset = 0;
|
||||
module.phdr_table.load1.p_vaddr = 0;
|
||||
module.phdr_table.load1.p_filesz = offsetof(decltype(module), shdr_table);
|
||||
module.phdr_table.load1.p_memsz = offsetof(decltype(module), shdr_table);
|
||||
module.phdr_table.load1.p_flags = PF_R;
|
||||
module.phdr_table.load1.p_align = load2_vaddr;
|
||||
|
||||
module.phdr_table.load2.p_type = PT_LOAD;
|
||||
module.phdr_table.load2.p_offset = 0;
|
||||
module.phdr_table.load2.p_vaddr = load2_vaddr;
|
||||
module.phdr_table.load2.p_filesz = offsetof(decltype(module), shdr_table);
|
||||
module.phdr_table.load2.p_memsz = offsetof(decltype(module), shdr_table);
|
||||
module.phdr_table.load2.p_flags = PF_R | PF_W;
|
||||
module.phdr_table.load2.p_align = load2_vaddr;
|
||||
|
||||
module.phdr_table.dynamic.p_type = PT_DYNAMIC;
|
||||
module.phdr_table.dynamic.p_offset =
|
||||
offsetof(decltype(module), dynamic_array);
|
||||
module.phdr_table.dynamic.p_vaddr =
|
||||
load2_vaddr + module.phdr_table.dynamic.p_offset;
|
||||
module.phdr_table.dynamic.p_filesz = sizeof(module.dynamic_array);
|
||||
module.phdr_table.dynamic.p_memsz = sizeof(module.dynamic_array);
|
||||
module.phdr_table.dynamic.p_flags = PF_R | PF_W;
|
||||
module.phdr_table.dynamic.p_align = 8;
|
||||
|
||||
module.dynamic_array.hash.d_tag = DT_HASH;
|
||||
module.dynamic_array.hash.d_un.d_ptr = offsetof(decltype(module), hash_table);
|
||||
module.dynamic_array.strtab.d_tag = DT_STRTAB;
|
||||
module.dynamic_array.strtab.d_un.d_ptr =
|
||||
offsetof(decltype(module), string_table);
|
||||
module.dynamic_array.symtab.d_tag = DT_SYMTAB;
|
||||
module.dynamic_array.symtab.d_un.d_ptr =
|
||||
offsetof(decltype(module), symbol_table);
|
||||
module.dynamic_array.strsz.d_tag = DT_STRSZ;
|
||||
module.dynamic_array.strsz.d_un.d_val = sizeof(module.string_table);
|
||||
module.dynamic_array.syment.d_tag = DT_SYMENT;
|
||||
module.dynamic_array.syment.d_un.d_val = sizeof(Sym);
|
||||
constexpr size_t kSonameOffset = 1;
|
||||
module.dynamic_array.soname.d_tag = DT_SONAME;
|
||||
module.dynamic_array.soname.d_un.d_val = kSonameOffset;
|
||||
|
||||
module.dynamic_array.null.d_tag = DT_NULL;
|
||||
|
||||
module.hash_table.nbucket = 1;
|
||||
module.hash_table.nchain = 1;
|
||||
module.hash_table.bucket = 0;
|
||||
module.hash_table.chain = 0;
|
||||
|
||||
if (sizeof(module.string_table) < soname.size() + 2) {
|
||||
ADD_FAILURE() << "string table too small";
|
||||
return false;
|
||||
}
|
||||
module.string_table[0] = '\0';
|
||||
memcpy(&module.string_table[kSonameOffset], soname.c_str(), soname.size());
|
||||
|
||||
module.shdr_table.null.sh_type = SHT_NULL;
|
||||
|
||||
module.shdr_table.dynamic.sh_name = 0;
|
||||
module.shdr_table.dynamic.sh_type = SHT_DYNAMIC;
|
||||
module.shdr_table.dynamic.sh_flags = SHF_WRITE | SHF_ALLOC;
|
||||
module.shdr_table.dynamic.sh_addr = module.phdr_table.dynamic.p_vaddr;
|
||||
module.shdr_table.dynamic.sh_offset = module.phdr_table.dynamic.p_offset;
|
||||
module.shdr_table.dynamic.sh_size = module.phdr_table.dynamic.p_filesz;
|
||||
module.shdr_table.dynamic.sh_link =
|
||||
offsetof(decltype(module.shdr_table), string_table) / sizeof(Shdr);
|
||||
|
||||
module.shdr_table.string_table.sh_name = 0;
|
||||
module.shdr_table.string_table.sh_type = SHT_STRTAB;
|
||||
module.shdr_table.string_table.sh_offset =
|
||||
offsetof(decltype(module), string_table);
|
||||
module.shdr_table.string_table.sh_size = sizeof(module.string_table);
|
||||
|
||||
module.shdr_table.section_header_string_table.sh_name = 0;
|
||||
module.shdr_table.section_header_string_table.sh_type = SHT_STRTAB;
|
||||
module.shdr_table.section_header_string_table.sh_offset =
|
||||
offsetof(decltype(module), section_header_string_table);
|
||||
module.shdr_table.section_header_string_table.sh_size =
|
||||
sizeof(module.section_header_string_table);
|
||||
|
||||
FileWriter writer;
|
||||
if (!writer.Open(module_path,
|
||||
FileWriteMode::kCreateOrFail,
|
||||
FilePermissions::kWorldReadable)) {
|
||||
ADD_FAILURE();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!writer.Write(&module, sizeof(module))) {
|
||||
ADD_FAILURE();
|
||||
LoggingRemoveFile(module_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ScopedModuleHandle LoadTestModule(const std::string& module_name,
|
||||
const std::string& module_soname) {
|
||||
base::FilePath module_path(
|
||||
TestPaths::Executable().DirName().Append(module_name));
|
||||
|
||||
if (!WriteTestModule(module_path, module_soname)) {
|
||||
return ScopedModuleHandle(nullptr);
|
||||
}
|
||||
EXPECT_TRUE(IsRegularFile(module_path));
|
||||
|
||||
ScopedModuleHandle handle(
|
||||
dlopen(module_path.value().c_str(), RTLD_LAZY | RTLD_LOCAL));
|
||||
EXPECT_TRUE(handle.valid())
|
||||
<< "dlopen: " << module_path.value() << " " << dlerror();
|
||||
|
||||
EXPECT_TRUE(LoggingRemoveFile(module_path));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
37
snapshot/linux/test_modules.h
Normal file
37
snapshot/linux/test_modules.h
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2020 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CRASHPAD_SNAPSHOT_LINUX_TEST_MODULES_H_
|
||||
#define CRASHPAD_SNAPSHOT_LINUX_TEST_MODULES_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "test/scoped_module_handle.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
//! \brief Constructs and loads a test module.
|
||||
//!
|
||||
//! \param module_name The filename of the mdoule.
|
||||
//! \param module_soname The SONAME for the module.
|
||||
//! \return a handle to the loaded module on success. On failure, the handle
|
||||
//! will be invalid and a message will be logged.
|
||||
ScopedModuleHandle LoadTestModule(const std::string& module_name,
|
||||
const std::string& module_soname);
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_SNAPSHOT_LINUX_DEBUG_RENDEZVOUS_H_
|
@ -80,6 +80,8 @@
|
||||
'linux/exception_snapshot_linux_test.cc',
|
||||
'linux/process_reader_linux_test.cc',
|
||||
'linux/system_snapshot_linux_test.cc',
|
||||
'linux/test_modules.cc',
|
||||
'linux/test_modules.h',
|
||||
'mac/cpu_context_mac_test.cc',
|
||||
'mac/mach_o_image_annotations_reader_test.cc',
|
||||
'mac/mach_o_image_reader_test.cc',
|
||||
|
Loading…
x
Reference in New Issue
Block a user