mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-26 23:01:05 +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) {
|
||||
sources += [
|
||||
"crashpad_types/image_annotation_reader.cc",
|
||||
"crashpad_types/image_annotation_reader.h",
|
||||
"linux/cpu_context_linux.cc",
|
||||
"linux/cpu_context_linux.h",
|
||||
"linux/debug_rendezvous.cc",
|
||||
@ -134,6 +132,8 @@ static_library("snapshot") {
|
||||
sources += [
|
||||
"crashpad_types/crashpad_info_reader.cc",
|
||||
"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.h",
|
||||
"elf/elf_image_reader.cc",
|
||||
@ -307,7 +307,6 @@ source_set("snapshot_test") {
|
||||
|
||||
if (crashpad_is_linux || crashpad_is_android) {
|
||||
sources += [
|
||||
"crashpad_types/image_annotation_reader_test.cc",
|
||||
"linux/debug_rendezvous_test.cc",
|
||||
"linux/exception_snapshot_linux_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) {
|
||||
sources += [
|
||||
"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_note.S",
|
||||
"elf/test_exported_symbols.sym",
|
||||
|
@ -26,11 +26,12 @@
|
||||
#include "client/annotation_list.h"
|
||||
#include "client/simple_string_dictionary.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/misc/as_underlying_type.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 test {
|
||||
@ -60,67 +61,64 @@ void ExpectAnnotationList(const std::vector<AnnotationSnapshot>& list,
|
||||
}
|
||||
}
|
||||
|
||||
class AnnotationTest {
|
||||
public:
|
||||
AnnotationTest()
|
||||
: expected_simple_map_(),
|
||||
test_annotations_(),
|
||||
expected_annotation_list_() {
|
||||
expected_simple_map_.SetKeyValue("key", "value");
|
||||
expected_simple_map_.SetKeyValue("key2", "value2");
|
||||
void BuildTestStructures(
|
||||
std::vector<std::unique_ptr<Annotation>>* annotations_storage,
|
||||
SimpleStringDictionary* into_map,
|
||||
AnnotationList* into_annotation_list) {
|
||||
into_map->SetKeyValue("key", "value");
|
||||
into_map->SetKeyValue("key2", "value2");
|
||||
|
||||
static constexpr char kAnnotationName[] = "test annotation";
|
||||
static constexpr char kAnnotationValue[] = "test annotation value";
|
||||
test_annotations_.push_back(std::make_unique<Annotation>(
|
||||
Annotation::Type::kString,
|
||||
kAnnotationName,
|
||||
reinterpret_cast<void*>(const_cast<char*>(kAnnotationValue))));
|
||||
test_annotations_.back()->SetSize(sizeof(kAnnotationValue));
|
||||
expected_annotation_list_.Add(test_annotations_.back().get());
|
||||
static constexpr char kAnnotationName[] = "test annotation";
|
||||
static constexpr char kAnnotationValue[] = "test annotation value";
|
||||
annotations_storage->push_back(std::make_unique<Annotation>(
|
||||
Annotation::Type::kString,
|
||||
kAnnotationName,
|
||||
reinterpret_cast<void*>(const_cast<char*>(kAnnotationValue))));
|
||||
annotations_storage->back()->SetSize(sizeof(kAnnotationValue));
|
||||
into_annotation_list->Add(annotations_storage->back().get());
|
||||
|
||||
static constexpr char kAnnotationName2[] = "test annotation2";
|
||||
static constexpr char kAnnotationValue2[] = "test annotation value2";
|
||||
test_annotations_.push_back(std::make_unique<Annotation>(
|
||||
Annotation::Type::kString,
|
||||
kAnnotationName2,
|
||||
reinterpret_cast<void*>(const_cast<char*>(kAnnotationValue2))));
|
||||
test_annotations_.back()->SetSize(sizeof(kAnnotationValue2));
|
||||
expected_annotation_list_.Add(test_annotations_.back().get());
|
||||
}
|
||||
static constexpr char kAnnotationName2[] = "test annotation2";
|
||||
static constexpr char kAnnotationValue2[] = "test annotation value2";
|
||||
annotations_storage->push_back(std::make_unique<Annotation>(
|
||||
Annotation::Type::kString,
|
||||
kAnnotationName2,
|
||||
reinterpret_cast<void*>(const_cast<char*>(kAnnotationValue2))));
|
||||
annotations_storage->back()->SetSize(sizeof(kAnnotationValue2));
|
||||
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) {
|
||||
ProcessMemoryLinux memory;
|
||||
ASSERT_TRUE(memory.Initialize(pid));
|
||||
ProcessMemoryRange range;
|
||||
ASSERT_TRUE(range.Initialize(&memory, is_64_bit));
|
||||
|
||||
ProcessMemoryRange range;
|
||||
ASSERT_TRUE(range.Initialize(&memory, is_64_bit));
|
||||
SimpleStringDictionary expected_simple_map;
|
||||
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;
|
||||
ASSERT_TRUE(reader.SimpleMap(
|
||||
FromPointerCast<VMAddress>(&expected_simple_map_), &simple_map));
|
||||
ExpectSimpleMap(simple_map, expected_simple_map_);
|
||||
std::map<std::string, std::string> simple_map;
|
||||
ASSERT_TRUE(reader.SimpleMap(simple_map_address, &simple_map));
|
||||
ExpectSimpleMap(simple_map, expected_simple_map);
|
||||
|
||||
std::vector<AnnotationSnapshot> annotation_list;
|
||||
ASSERT_TRUE(reader.AnnotationsList(
|
||||
FromPointerCast<VMAddress>(&expected_annotation_list_),
|
||||
&annotation_list));
|
||||
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);
|
||||
};
|
||||
std::vector<AnnotationSnapshot> annotation_list;
|
||||
ASSERT_TRUE(
|
||||
reader.AnnotationsList(annotation_list_address, &annotation_list));
|
||||
ExpectAnnotationList(annotation_list, expected_annotations);
|
||||
}
|
||||
|
||||
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)
|
||||
constexpr bool am_64_bit = true;
|
||||
@ -128,14 +126,35 @@ TEST(ImageAnnotationReader, ReadFromSelf) {
|
||||
constexpr bool am_64_bit = false;
|
||||
#endif
|
||||
|
||||
test.ExpectAnnotations(getpid(), am_64_bit);
|
||||
ExpectAnnotations(GetSelfProcess(),
|
||||
am_64_bit,
|
||||
FromPointerCast<VMAddress>(&map),
|
||||
FromPointerCast<VMAddress>(&annotations));
|
||||
}
|
||||
|
||||
class ReadFromChildTest : public Multiprocess {
|
||||
public:
|
||||
ReadFromChildTest() : Multiprocess(), annotation_test_() {}
|
||||
CRASHPAD_CHILD_TEST_MAIN(ReadAnnotationsFromChildTestMain) {
|
||||
SimpleStringDictionary map;
|
||||
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:
|
||||
void MultiprocessParent() {
|
||||
@ -144,13 +163,17 @@ class ReadFromChildTest : public Multiprocess {
|
||||
#else
|
||||
constexpr bool am_64_bit = false;
|
||||
#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);
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user