| Index: snapshot/win/pe_image_annotations_reader_test.cc
|
| diff --git a/snapshot/win/pe_image_annotations_reader_test.cc b/snapshot/win/pe_image_annotations_reader_test.cc
|
| index 2c88417d0a49dd8e53c36f0fff3451aa0569748e..a37ac1eff34387e211abb2a76d2226e5360c8b80 100644
|
| --- a/snapshot/win/pe_image_annotations_reader_test.cc
|
| +++ b/snapshot/win/pe_image_annotations_reader_test.cc
|
| @@ -22,12 +22,15 @@
|
| #include <vector>
|
|
|
| #include "base/basictypes.h"
|
| +#include "base/files/file_path.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "client/crashpad_info.h"
|
| #include "client/simple_string_dictionary.h"
|
| #include "gtest/gtest.h"
|
| #include "snapshot/win/pe_image_reader.h"
|
| #include "snapshot/win/process_reader_win.h"
|
| +#include "test/paths.h"
|
| +#include "test/win/child_launcher.h"
|
| #include "test/win/win_multiprocess.h"
|
| #include "util/file/file_io.h"
|
| #include "util/win/process_info.h"
|
| @@ -44,97 +47,98 @@ enum TestType {
|
| kCrashDebugBreak,
|
| };
|
|
|
| -template <TestType Type>
|
| -class TestPEImageAnnotationsReader final : public WinMultiprocess {
|
| - public:
|
| - TestPEImageAnnotationsReader() {}
|
| - ~TestPEImageAnnotationsReader() {}
|
| -
|
| - private:
|
| - // WinMultiprocess:
|
| -
|
| - void WinMultiprocessParent() override {
|
| - ProcessReaderWin process_reader;
|
| - ASSERT_TRUE(process_reader.Initialize(ChildProcess(),
|
| - ProcessSuspensionState::kRunning));
|
| -
|
| - // Wait for the child process to indicate that it's done setting up its
|
| - // annotations via the CrashpadInfo interface.
|
| - char c;
|
| - CheckedReadFile(ReadPipeHandle(), &c, sizeof(c));
|
| -
|
| - // Verify the "simple map" annotations set via the CrashpadInfo interface.
|
| - const std::vector<ProcessInfo::Module>& modules = process_reader.Modules();
|
| - std::map<std::string, std::string> all_annotations_simple_map;
|
| - for (const ProcessInfo::Module& module : modules) {
|
| - PEImageReader pe_image_reader;
|
| - pe_image_reader.Initialize(&process_reader,
|
| - module.dll_base,
|
| - module.size,
|
| - base::UTF16ToUTF8(module.name));
|
| - PEImageAnnotationsReader module_annotations_reader(
|
| - &process_reader, &pe_image_reader, module.name);
|
| - std::map<std::string, std::string> module_annotations_simple_map =
|
| - module_annotations_reader.SimpleMap();
|
| - all_annotations_simple_map.insert(module_annotations_simple_map.begin(),
|
| - module_annotations_simple_map.end());
|
| - }
|
| -
|
| - EXPECT_GE(all_annotations_simple_map.size(), 5u);
|
| - EXPECT_EQ("crash", all_annotations_simple_map["#TEST# pad"]);
|
| - EXPECT_EQ("value", all_annotations_simple_map["#TEST# key"]);
|
| - EXPECT_EQ("y", all_annotations_simple_map["#TEST# x"]);
|
| - EXPECT_EQ("shorter", all_annotations_simple_map["#TEST# longer"]);
|
| - EXPECT_EQ("", all_annotations_simple_map["#TEST# empty_value"]);
|
| -
|
| - if (Type == kCrashDebugBreak)
|
| - SetExpectedChildExitCode(STATUS_BREAKPOINT);
|
| -
|
| - // Tell the child process to continue.
|
| - CheckedWriteFile(WritePipeHandle(), &c, sizeof(c));
|
| +void TestAnnotationsOnCrash(TestType type,
|
| + const base::string16& directory_modification) {
|
| + // Spawn a child process, passing it the pipe name to connect to.
|
| + base::FilePath test_executable = Paths::Executable();
|
| + std::wstring child_test_executable =
|
| + test_executable.DirName()
|
| + .Append(directory_modification)
|
| + .Append(test_executable.BaseName().RemoveFinalExtension().value() +
|
| + L"_simple_annotations.exe")
|
| + .value();
|
| + ChildLauncher child(child_test_executable, L"");
|
| + child.Start();
|
| +
|
| + // Wait for the child process to indicate that it's done setting up its
|
| + // annotations via the CrashpadInfo interface.
|
| + char c;
|
| + CheckedReadFile(child.stdout_read_handle(), &c, sizeof(c));
|
| +
|
| + ProcessReaderWin process_reader;
|
| + ASSERT_TRUE(process_reader.Initialize(child.process_handle(),
|
| + ProcessSuspensionState::kRunning));
|
| +
|
| + // Verify the "simple map" annotations set via the CrashpadInfo interface.
|
| + const std::vector<ProcessInfo::Module>& modules = process_reader.Modules();
|
| + std::map<std::string, std::string> all_annotations_simple_map;
|
| + for (const ProcessInfo::Module& module : modules) {
|
| + PEImageReader pe_image_reader;
|
| + pe_image_reader.Initialize(&process_reader,
|
| + module.dll_base,
|
| + module.size,
|
| + base::UTF16ToUTF8(module.name));
|
| + PEImageAnnotationsReader module_annotations_reader(
|
| + &process_reader, &pe_image_reader, module.name);
|
| + std::map<std::string, std::string> module_annotations_simple_map =
|
| + module_annotations_reader.SimpleMap();
|
| + all_annotations_simple_map.insert(module_annotations_simple_map.begin(),
|
| + module_annotations_simple_map.end());
|
| }
|
|
|
| - void WinMultiprocessChild() override {
|
| - CrashpadInfo* crashpad_info = CrashpadInfo::GetCrashpadInfo();
|
| -
|
| - // This is "leaked" to crashpad_info.
|
| - SimpleStringDictionary* simple_annotations = new SimpleStringDictionary();
|
| - simple_annotations->SetKeyValue("#TEST# pad", "break");
|
| - simple_annotations->SetKeyValue("#TEST# key", "value");
|
| - simple_annotations->SetKeyValue("#TEST# pad", "crash");
|
| - simple_annotations->SetKeyValue("#TEST# x", "y");
|
| - simple_annotations->SetKeyValue("#TEST# longer", "shorter");
|
| - simple_annotations->SetKeyValue("#TEST# empty_value", "");
|
| -
|
| - crashpad_info->set_simple_annotations(simple_annotations);
|
| -
|
| - // Tell the parent that the environment has been set up.
|
| - char c = '\0';
|
| - CheckedWriteFile(WritePipeHandle(), &c, sizeof(c));
|
| -
|
| - // Wait for the parent to indicate that it's safe to continue/crash.
|
| - CheckedReadFile(ReadPipeHandle(), &c, sizeof(c));
|
| -
|
| - switch (Type) {
|
| - case kDontCrash:
|
| - break;
|
| -
|
| - case kCrashDebugBreak:
|
| - __debugbreak();
|
| - break;
|
| - }
|
| + EXPECT_GE(all_annotations_simple_map.size(), 5u);
|
| + EXPECT_EQ("crash", all_annotations_simple_map["#TEST# pad"]);
|
| + EXPECT_EQ("value", all_annotations_simple_map["#TEST# key"]);
|
| + EXPECT_EQ("y", all_annotations_simple_map["#TEST# x"]);
|
| + EXPECT_EQ("shorter", all_annotations_simple_map["#TEST# longer"]);
|
| + EXPECT_EQ("", all_annotations_simple_map["#TEST# empty_value"]);
|
| +
|
| + // Tell the child process to continue.
|
| + DWORD expected_exit_code;
|
| + switch (type) {
|
| + case kDontCrash:
|
| + c = ' ';
|
| + expected_exit_code = 0;
|
| + break;
|
| + case kCrashDebugBreak:
|
| + c = 'd';
|
| + expected_exit_code = STATUS_BREAKPOINT;
|
| + break;
|
| + default:
|
| + FAIL();
|
| }
|
| + CheckedWriteFile(child.stdin_write_handle(), &c, sizeof(c));
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(TestPEImageAnnotationsReader);
|
| -};
|
| + EXPECT_EQ(expected_exit_code, child.WaitForExit());
|
| +}
|
|
|
| TEST(PEImageAnnotationsReader, DontCrash) {
|
| - WinMultiprocess::Run<TestPEImageAnnotationsReader<kDontCrash>>();
|
| + TestAnnotationsOnCrash(kDontCrash, FILE_PATH_LITERAL("."));
|
| }
|
|
|
| TEST(PEImageAnnotationsReader, CrashDebugBreak) {
|
| - WinMultiprocess::Run<TestPEImageAnnotationsReader<kCrashDebugBreak>>();
|
| + TestAnnotationsOnCrash(kCrashDebugBreak, FILE_PATH_LITERAL("."));
|
| +}
|
| +
|
| +#if defined(ARCH_CPU_64_BITS)
|
| +TEST(PEImageAnnotationsReader, DontCrashWOW64) {
|
| +#ifndef NDEBUG
|
| + TestAnnotationsOnCrash(kDontCrash, FILE_PATH_LITERAL("..\\..\\out\\Debug"));
|
| +#else
|
| + TestAnnotationsOnCrash(kDontCrash, FILE_PATH_LITERAL("..\\..\\out\\Release"));
|
| +#endif
|
| +}
|
| +
|
| +TEST(PEImageAnnotationsReader, CrashDebugBreakWOW64) {
|
| +#ifndef NDEBUG
|
| + TestAnnotationsOnCrash(kCrashDebugBreak,
|
| + FILE_PATH_LITERAL("..\\..\\out\\Debug"));
|
| +#else
|
| + TestAnnotationsOnCrash(kCrashDebugBreak,
|
| + FILE_PATH_LITERAL("..\\..\\out\\Release"));
|
| +#endif
|
| }
|
| +#endif // ARCH_CPU_64_BITS
|
|
|
| } // namespace
|
| } // namespace test
|
|
|