mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-28 07:48:14 +08:00
fuchsia: Make ImageAnnotationReader[Test] work
Ports the test away from fork() to MultiprocessExec. Requires a Fuchsia SDK that includes the fix in https://fuchsia-review.googlesource.com/c/zircon/+/125081. Bug: crashpad:196, crashpad:215 Change-Id: Ia8d382cebe8d2ffc8d877e5249baf0e58aee248c Reviewed-on: https://chromium-review.googlesource.com/927355 Commit-Queue: Scott Graham <scottmg@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
01105719d7
commit
3dd85dc126
@ -106,8 +106,6 @@ static_library("snapshot") {
|
|||||||
|
|
||||||
if (crashpad_is_linux || crashpad_is_android) {
|
if (crashpad_is_linux || crashpad_is_android) {
|
||||||
sources += [
|
sources += [
|
||||||
"crashpad_types/image_annotation_reader.cc",
|
|
||||||
"crashpad_types/image_annotation_reader.h",
|
|
||||||
"linux/cpu_context_linux.cc",
|
"linux/cpu_context_linux.cc",
|
||||||
"linux/cpu_context_linux.h",
|
"linux/cpu_context_linux.h",
|
||||||
"linux/debug_rendezvous.cc",
|
"linux/debug_rendezvous.cc",
|
||||||
@ -134,6 +132,8 @@ static_library("snapshot") {
|
|||||||
sources += [
|
sources += [
|
||||||
"crashpad_types/crashpad_info_reader.cc",
|
"crashpad_types/crashpad_info_reader.cc",
|
||||||
"crashpad_types/crashpad_info_reader.h",
|
"crashpad_types/crashpad_info_reader.h",
|
||||||
|
"crashpad_types/image_annotation_reader.cc",
|
||||||
|
"crashpad_types/image_annotation_reader.h",
|
||||||
"elf/elf_dynamic_array_reader.cc",
|
"elf/elf_dynamic_array_reader.cc",
|
||||||
"elf/elf_dynamic_array_reader.h",
|
"elf/elf_dynamic_array_reader.h",
|
||||||
"elf/elf_image_reader.cc",
|
"elf/elf_image_reader.cc",
|
||||||
@ -307,7 +307,6 @@ source_set("snapshot_test") {
|
|||||||
|
|
||||||
if (crashpad_is_linux || crashpad_is_android) {
|
if (crashpad_is_linux || crashpad_is_android) {
|
||||||
sources += [
|
sources += [
|
||||||
"crashpad_types/image_annotation_reader_test.cc",
|
|
||||||
"linux/debug_rendezvous_test.cc",
|
"linux/debug_rendezvous_test.cc",
|
||||||
"linux/exception_snapshot_linux_test.cc",
|
"linux/exception_snapshot_linux_test.cc",
|
||||||
"linux/process_reader_test.cc",
|
"linux/process_reader_test.cc",
|
||||||
@ -320,6 +319,7 @@ source_set("snapshot_test") {
|
|||||||
if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
|
if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
|
||||||
sources += [
|
sources += [
|
||||||
"crashpad_types/crashpad_info_reader_test.cc",
|
"crashpad_types/crashpad_info_reader_test.cc",
|
||||||
|
"crashpad_types/image_annotation_reader_test.cc",
|
||||||
"elf/elf_image_reader_test.cc",
|
"elf/elf_image_reader_test.cc",
|
||||||
"elf/elf_image_reader_test_note.S",
|
"elf/elf_image_reader_test_note.S",
|
||||||
"elf/test_exported_symbols.sym",
|
"elf/test_exported_symbols.sym",
|
||||||
|
@ -26,11 +26,12 @@
|
|||||||
#include "client/annotation_list.h"
|
#include "client/annotation_list.h"
|
||||||
#include "client/simple_string_dictionary.h"
|
#include "client/simple_string_dictionary.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "test/multiprocess.h"
|
#include "test/multiprocess_exec.h"
|
||||||
|
#include "test/process_type.h"
|
||||||
#include "util/file/file_io.h"
|
#include "util/file/file_io.h"
|
||||||
#include "util/misc/as_underlying_type.h"
|
#include "util/misc/as_underlying_type.h"
|
||||||
#include "util/misc/from_pointer_cast.h"
|
#include "util/misc/from_pointer_cast.h"
|
||||||
#include "util/process/process_memory_linux.h"
|
#include "util/process/process_memory_native.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
namespace test {
|
namespace test {
|
||||||
@ -60,67 +61,64 @@ void ExpectAnnotationList(const std::vector<AnnotationSnapshot>& list,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AnnotationTest {
|
void BuildTestStructures(
|
||||||
public:
|
std::vector<std::unique_ptr<Annotation>>* annotations_storage,
|
||||||
AnnotationTest()
|
SimpleStringDictionary* into_map,
|
||||||
: expected_simple_map_(),
|
AnnotationList* into_annotation_list) {
|
||||||
test_annotations_(),
|
into_map->SetKeyValue("key", "value");
|
||||||
expected_annotation_list_() {
|
into_map->SetKeyValue("key2", "value2");
|
||||||
expected_simple_map_.SetKeyValue("key", "value");
|
|
||||||
expected_simple_map_.SetKeyValue("key2", "value2");
|
|
||||||
|
|
||||||
static constexpr char kAnnotationName[] = "test annotation";
|
static constexpr char kAnnotationName[] = "test annotation";
|
||||||
static constexpr char kAnnotationValue[] = "test annotation value";
|
static constexpr char kAnnotationValue[] = "test annotation value";
|
||||||
test_annotations_.push_back(std::make_unique<Annotation>(
|
annotations_storage->push_back(std::make_unique<Annotation>(
|
||||||
Annotation::Type::kString,
|
Annotation::Type::kString,
|
||||||
kAnnotationName,
|
kAnnotationName,
|
||||||
reinterpret_cast<void*>(const_cast<char*>(kAnnotationValue))));
|
reinterpret_cast<void*>(const_cast<char*>(kAnnotationValue))));
|
||||||
test_annotations_.back()->SetSize(sizeof(kAnnotationValue));
|
annotations_storage->back()->SetSize(sizeof(kAnnotationValue));
|
||||||
expected_annotation_list_.Add(test_annotations_.back().get());
|
into_annotation_list->Add(annotations_storage->back().get());
|
||||||
|
|
||||||
static constexpr char kAnnotationName2[] = "test annotation2";
|
static constexpr char kAnnotationName2[] = "test annotation2";
|
||||||
static constexpr char kAnnotationValue2[] = "test annotation value2";
|
static constexpr char kAnnotationValue2[] = "test annotation value2";
|
||||||
test_annotations_.push_back(std::make_unique<Annotation>(
|
annotations_storage->push_back(std::make_unique<Annotation>(
|
||||||
Annotation::Type::kString,
|
Annotation::Type::kString,
|
||||||
kAnnotationName2,
|
kAnnotationName2,
|
||||||
reinterpret_cast<void*>(const_cast<char*>(kAnnotationValue2))));
|
reinterpret_cast<void*>(const_cast<char*>(kAnnotationValue2))));
|
||||||
test_annotations_.back()->SetSize(sizeof(kAnnotationValue2));
|
annotations_storage->back()->SetSize(sizeof(kAnnotationValue2));
|
||||||
expected_annotation_list_.Add(test_annotations_.back().get());
|
into_annotation_list->Add(annotations_storage->back().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
~AnnotationTest() = default;
|
void ExpectAnnotations(ProcessType process,
|
||||||
|
bool is_64_bit,
|
||||||
|
VMAddress simple_map_address,
|
||||||
|
VMAddress annotation_list_address) {
|
||||||
|
ProcessMemoryNative memory;
|
||||||
|
ASSERT_TRUE(memory.Initialize(process));
|
||||||
|
|
||||||
void ExpectAnnotations(pid_t pid, bool is_64_bit) {
|
ProcessMemoryRange range;
|
||||||
ProcessMemoryLinux memory;
|
ASSERT_TRUE(range.Initialize(&memory, is_64_bit));
|
||||||
ASSERT_TRUE(memory.Initialize(pid));
|
|
||||||
|
|
||||||
ProcessMemoryRange range;
|
SimpleStringDictionary expected_simple_map;
|
||||||
ASSERT_TRUE(range.Initialize(&memory, is_64_bit));
|
std::vector<std::unique_ptr<Annotation>> storage;
|
||||||
|
AnnotationList expected_annotations;
|
||||||
|
BuildTestStructures(&storage, &expected_simple_map, &expected_annotations);
|
||||||
|
|
||||||
ImageAnnotationReader reader(&range);
|
ImageAnnotationReader reader(&range);
|
||||||
|
|
||||||
std::map<std::string, std::string> simple_map;
|
std::map<std::string, std::string> simple_map;
|
||||||
ASSERT_TRUE(reader.SimpleMap(
|
ASSERT_TRUE(reader.SimpleMap(simple_map_address, &simple_map));
|
||||||
FromPointerCast<VMAddress>(&expected_simple_map_), &simple_map));
|
ExpectSimpleMap(simple_map, expected_simple_map);
|
||||||
ExpectSimpleMap(simple_map, expected_simple_map_);
|
|
||||||
|
|
||||||
std::vector<AnnotationSnapshot> annotation_list;
|
std::vector<AnnotationSnapshot> annotation_list;
|
||||||
ASSERT_TRUE(reader.AnnotationsList(
|
ASSERT_TRUE(
|
||||||
FromPointerCast<VMAddress>(&expected_annotation_list_),
|
reader.AnnotationsList(annotation_list_address, &annotation_list));
|
||||||
&annotation_list));
|
ExpectAnnotationList(annotation_list, expected_annotations);
|
||||||
ExpectAnnotationList(annotation_list, expected_annotation_list_);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
SimpleStringDictionary expected_simple_map_;
|
|
||||||
std::vector<std::unique_ptr<Annotation>> test_annotations_;
|
|
||||||
AnnotationList expected_annotation_list_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AnnotationTest);
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST(ImageAnnotationReader, ReadFromSelf) {
|
TEST(ImageAnnotationReader, ReadFromSelf) {
|
||||||
AnnotationTest test;
|
SimpleStringDictionary map;
|
||||||
|
std::vector<std::unique_ptr<Annotation>> storage;
|
||||||
|
AnnotationList annotations;
|
||||||
|
BuildTestStructures(&storage, &map, &annotations);
|
||||||
|
|
||||||
#if defined(ARCH_CPU_64_BITS)
|
#if defined(ARCH_CPU_64_BITS)
|
||||||
constexpr bool am_64_bit = true;
|
constexpr bool am_64_bit = true;
|
||||||
@ -128,14 +126,35 @@ TEST(ImageAnnotationReader, ReadFromSelf) {
|
|||||||
constexpr bool am_64_bit = false;
|
constexpr bool am_64_bit = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
test.ExpectAnnotations(getpid(), am_64_bit);
|
ExpectAnnotations(GetSelfProcess(),
|
||||||
|
am_64_bit,
|
||||||
|
FromPointerCast<VMAddress>(&map),
|
||||||
|
FromPointerCast<VMAddress>(&annotations));
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReadFromChildTest : public Multiprocess {
|
CRASHPAD_CHILD_TEST_MAIN(ReadAnnotationsFromChildTestMain) {
|
||||||
public:
|
SimpleStringDictionary map;
|
||||||
ReadFromChildTest() : Multiprocess(), annotation_test_() {}
|
std::vector<std::unique_ptr<Annotation>> storage;
|
||||||
|
AnnotationList annotations;
|
||||||
|
BuildTestStructures(&storage, &map, &annotations);
|
||||||
|
|
||||||
~ReadFromChildTest() {}
|
VMAddress simple_map_address = FromPointerCast<VMAddress>(&map);
|
||||||
|
VMAddress annotations_address = FromPointerCast<VMAddress>(&annotations);
|
||||||
|
FileHandle out = StdioFileHandle(StdioStream::kStandardOutput);
|
||||||
|
CheckedWriteFile(out, &simple_map_address, sizeof(simple_map_address));
|
||||||
|
CheckedWriteFile(out, &annotations_address, sizeof(annotations_address));
|
||||||
|
|
||||||
|
CheckedReadFileAtEOF(StdioFileHandle(StdioStream::kStandardInput));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReadFromChildTest : public MultiprocessExec {
|
||||||
|
public:
|
||||||
|
ReadFromChildTest() : MultiprocessExec() {
|
||||||
|
SetChildTestMainFunction("ReadAnnotationsFromChildTestMain");
|
||||||
|
}
|
||||||
|
|
||||||
|
~ReadFromChildTest() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void MultiprocessParent() {
|
void MultiprocessParent() {
|
||||||
@ -144,13 +163,17 @@ class ReadFromChildTest : public Multiprocess {
|
|||||||
#else
|
#else
|
||||||
constexpr bool am_64_bit = false;
|
constexpr bool am_64_bit = false;
|
||||||
#endif
|
#endif
|
||||||
annotation_test_.ExpectAnnotations(ChildPID(), am_64_bit);
|
|
||||||
|
VMAddress simple_map_address;
|
||||||
|
VMAddress annotations_address;
|
||||||
|
ASSERT_TRUE(ReadFileExactly(
|
||||||
|
ReadPipeHandle(), &simple_map_address, sizeof(simple_map_address)));
|
||||||
|
ASSERT_TRUE(ReadFileExactly(
|
||||||
|
ReadPipeHandle(), &annotations_address, sizeof(annotations_address)));
|
||||||
|
ExpectAnnotations(
|
||||||
|
ChildProcess(), am_64_bit, simple_map_address, annotations_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiprocessChild() { CheckedReadFileAtEOF(ReadPipeHandle()); }
|
|
||||||
|
|
||||||
AnnotationTest annotation_test_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(ReadFromChildTest);
|
DISALLOW_COPY_AND_ASSIGN(ReadFromChildTest);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user