Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: snapshot/win/pe_image_annotations_reader_test.cc

Issue 1355503005: win: Make reading CrashpadInfo work across bitness (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: nt_headers Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Crashpad Authors. All rights reserved. 1 // Copyright 2015 The Crashpad Authors. All rights reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 #include "snapshot/win/pe_image_annotations_reader.h" 15 #include "snapshot/win/pe_image_annotations_reader.h"
16 16
17 #include <stdlib.h> 17 #include <stdlib.h>
18 #include <string.h> 18 #include <string.h>
19 19
20 #include <map> 20 #include <map>
21 #include <string> 21 #include <string>
22 #include <vector> 22 #include <vector>
23 23
24 #include "base/basictypes.h" 24 #include "base/basictypes.h"
25 #include "base/files/file_path.h"
25 #include "base/strings/utf_string_conversions.h" 26 #include "base/strings/utf_string_conversions.h"
26 #include "client/crashpad_info.h" 27 #include "client/crashpad_info.h"
27 #include "client/simple_string_dictionary.h" 28 #include "client/simple_string_dictionary.h"
28 #include "gtest/gtest.h" 29 #include "gtest/gtest.h"
29 #include "snapshot/win/pe_image_reader.h" 30 #include "snapshot/win/pe_image_reader.h"
30 #include "snapshot/win/process_reader_win.h" 31 #include "snapshot/win/process_reader_win.h"
32 #include "test/paths.h"
33 #include "test/win/child_launcher.h"
31 #include "test/win/win_multiprocess.h" 34 #include "test/win/win_multiprocess.h"
32 #include "util/file/file_io.h" 35 #include "util/file/file_io.h"
33 #include "util/win/process_info.h" 36 #include "util/win/process_info.h"
34 37
35 namespace crashpad { 38 namespace crashpad {
36 namespace test { 39 namespace test {
37 namespace { 40 namespace {
38 41
39 enum TestType { 42 enum TestType {
40 // Don't crash, just test the CrashpadInfo interface. 43 // Don't crash, just test the CrashpadInfo interface.
41 kDontCrash = 0, 44 kDontCrash = 0,
42 45
43 // The child process should crash by __debugbreak(). 46 // The child process should crash by __debugbreak().
44 kCrashDebugBreak, 47 kCrashDebugBreak,
45 }; 48 };
46 49
47 template <TestType Type> 50 void TestAnnotationsOnCrash(TestType type,
48 class TestPEImageAnnotationsReader final : public WinMultiprocess { 51 const base::string16& directory_modification) {
49 public: 52 // Spawn a child process, passing it the pipe name to connect to.
50 TestPEImageAnnotationsReader() {} 53 base::FilePath test_executable = Paths::Executable();
51 ~TestPEImageAnnotationsReader() {} 54 std::wstring child_test_executable =
55 test_executable.DirName()
56 .Append(directory_modification)
57 .Append(test_executable.BaseName().RemoveFinalExtension().value() +
58 L"_simple_annotations.exe")
59 .value();
60 ChildLauncher child(child_test_executable, L"");
61 child.Start();
52 62
53 private: 63 // Wait for the child process to indicate that it's done setting up its
54 // WinMultiprocess: 64 // annotations via the CrashpadInfo interface.
65 char c;
66 CheckedReadFile(child.stdout_read_handle(), &c, sizeof(c));
55 67
56 void WinMultiprocessParent() override { 68 ProcessReaderWin process_reader;
57 ProcessReaderWin process_reader; 69 ASSERT_TRUE(process_reader.Initialize(child.process_handle(),
58 ASSERT_TRUE(process_reader.Initialize(ChildProcess(), 70 » ProcessSuspensionState::kRunning));
Mark Mentovai 2015/09/22 13:17:29 Spotted a tab here.
scottmg 2015/09/22 17:25:59 Gah, new OS install and haven't reconfigured every
59 ProcessSuspensionState::kRunning));
60 71
61 // Wait for the child process to indicate that it's done setting up its 72 // Verify the "simple map" annotations set via the CrashpadInfo interface.
62 // annotations via the CrashpadInfo interface. 73 const std::vector<ProcessInfo::Module>& modules = process_reader.Modules();
63 char c; 74 std::map<std::string, std::string> all_annotations_simple_map;
64 CheckedReadFile(ReadPipeHandle(), &c, sizeof(c)); 75 for (const ProcessInfo::Module& module : modules) {
65 76 PEImageReader pe_image_reader;
66 // Verify the "simple map" annotations set via the CrashpadInfo interface. 77 pe_image_reader.Initialize(&process_reader,
67 const std::vector<ProcessInfo::Module>& modules = process_reader.Modules(); 78 module.dll_base,
68 std::map<std::string, std::string> all_annotations_simple_map; 79 module.size,
69 for (const ProcessInfo::Module& module : modules) { 80 base::UTF16ToUTF8(module.name));
70 PEImageReader pe_image_reader; 81 PEImageAnnotationsReader module_annotations_reader(
71 pe_image_reader.Initialize(&process_reader, 82 &process_reader, &pe_image_reader, module.name);
72 module.dll_base, 83 std::map<std::string, std::string> module_annotations_simple_map =
73 module.size, 84 module_annotations_reader.SimpleMap();
74 base::UTF16ToUTF8(module.name)); 85 all_annotations_simple_map.insert(module_annotations_simple_map.begin(),
75 PEImageAnnotationsReader module_annotations_reader( 86 module_annotations_simple_map.end());
76 &process_reader, &pe_image_reader, module.name);
77 std::map<std::string, std::string> module_annotations_simple_map =
78 module_annotations_reader.SimpleMap();
79 all_annotations_simple_map.insert(module_annotations_simple_map.begin(),
80 module_annotations_simple_map.end());
81 }
82
83 EXPECT_GE(all_annotations_simple_map.size(), 5u);
84 EXPECT_EQ("crash", all_annotations_simple_map["#TEST# pad"]);
85 EXPECT_EQ("value", all_annotations_simple_map["#TEST# key"]);
86 EXPECT_EQ("y", all_annotations_simple_map["#TEST# x"]);
87 EXPECT_EQ("shorter", all_annotations_simple_map["#TEST# longer"]);
88 EXPECT_EQ("", all_annotations_simple_map["#TEST# empty_value"]);
89
90 if (Type == kCrashDebugBreak)
91 SetExpectedChildExitCode(STATUS_BREAKPOINT);
92
93 // Tell the child process to continue.
94 CheckedWriteFile(WritePipeHandle(), &c, sizeof(c));
95 } 87 }
96 88
97 void WinMultiprocessChild() override { 89 EXPECT_GE(all_annotations_simple_map.size(), 5u);
98 CrashpadInfo* crashpad_info = CrashpadInfo::GetCrashpadInfo(); 90 EXPECT_EQ("crash", all_annotations_simple_map["#TEST# pad"]);
91 EXPECT_EQ("value", all_annotations_simple_map["#TEST# key"]);
92 EXPECT_EQ("y", all_annotations_simple_map["#TEST# x"]);
93 EXPECT_EQ("shorter", all_annotations_simple_map["#TEST# longer"]);
94 EXPECT_EQ("", all_annotations_simple_map["#TEST# empty_value"]);
99 95
100 // This is "leaked" to crashpad_info. 96 // Tell the child process to continue.
101 SimpleStringDictionary* simple_annotations = new SimpleStringDictionary(); 97 switch (type) {
102 simple_annotations->SetKeyValue("#TEST# pad", "break"); 98 case kDontCrash:
103 simple_annotations->SetKeyValue("#TEST# key", "value"); 99 c = ' ';
104 simple_annotations->SetKeyValue("#TEST# pad", "crash"); 100 break;
105 simple_annotations->SetKeyValue("#TEST# x", "y"); 101 case kCrashDebugBreak:
106 simple_annotations->SetKeyValue("#TEST# longer", "shorter"); 102 c = 'd';
107 simple_annotations->SetKeyValue("#TEST# empty_value", ""); 103 break;
104 default:
105 ADD_FAILURE();
Mark Mentovai 2015/09/22 13:17:29 Should this be FAIL() instead to cause an immediat
scottmg 2015/09/22 17:25:59 Done.
106 }
107 CheckedWriteFile(child.stdin_write_handle(), &c, sizeof(c));
108 108
109 crashpad_info->set_simple_annotations(simple_annotations); 109 DWORD exit_code = child.WaitForExit();
110 110 switch (type) {
Mark Mentovai 2015/09/22 13:17:29 Optional: instead of having two switches on the sa
scottmg 2015/09/22 17:25:59 Done.
111 // Tell the parent that the environment has been set up. 111 case kDontCrash:
112 char c = '\0'; 112 EXPECT_EQ(0, exit_code);
113 CheckedWriteFile(WritePipeHandle(), &c, sizeof(c)); 113 break;
114 114 case kCrashDebugBreak:
115 // Wait for the parent to indicate that it's safe to continue/crash. 115 EXPECT_EQ(STATUS_BREAKPOINT, exit_code);
116 CheckedReadFile(ReadPipeHandle(), &c, sizeof(c)); 116 break;
117 117 default:
118 switch (Type) { 118 ADD_FAILURE();
119 case kDontCrash:
120 break;
121
122 case kCrashDebugBreak:
123 __debugbreak();
124 break;
125 }
126 } 119 }
127 120 }
128 DISALLOW_COPY_AND_ASSIGN(TestPEImageAnnotationsReader);
129 };
130 121
131 TEST(PEImageAnnotationsReader, DontCrash) { 122 TEST(PEImageAnnotationsReader, DontCrash) {
132 WinMultiprocess::Run<TestPEImageAnnotationsReader<kDontCrash>>(); 123 TestAnnotationsOnCrash(kDontCrash, FILE_PATH_LITERAL("."));
133 } 124 }
134 125
135 TEST(PEImageAnnotationsReader, CrashDebugBreak) { 126 TEST(PEImageAnnotationsReader, CrashDebugBreak) {
136 WinMultiprocess::Run<TestPEImageAnnotationsReader<kCrashDebugBreak>>(); 127 TestAnnotationsOnCrash(kCrashDebugBreak, FILE_PATH_LITERAL("."));
137 } 128 }
138 129
130 #if defined(ARCH_CPU_64_BITS)
131 TEST(PEImageAnnotationsReader, DontCrashWOW64) {
132 #ifndef NDEBUG
133 TestAnnotationsOnCrash(kDontCrash, FILE_PATH_LITERAL("..\\..\\out\\Debug"));
134 #else
135 TestAnnotationsOnCrash(kDontCrash, FILE_PATH_LITERAL("..\\..\\out\\Release"));
136 #endif
137 }
138
139 TEST(PEImageAnnotationsReader, CrashDebugBreakWOW64) {
140 #ifndef NDEBUG
141 TestAnnotationsOnCrash(kCrashDebugBreak,
142 FILE_PATH_LITERAL("..\\..\\out\\Debug"));
143 #else
144 TestAnnotationsOnCrash(kCrashDebugBreak,
145 FILE_PATH_LITERAL("..\\..\\out\\Release"));
146 #endif
147 }
148 #endif // ARCH_CPU_64_BITS
149
139 } // namespace 150 } // namespace
140 } // namespace test 151 } // namespace test
141 } // namespace crashpad 152 } // namespace crashpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698