OLD | NEW |
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 "util/win/exception_handler_server.h" | 15 #include "util/win/exception_handler_server.h" |
16 | 16 |
17 #include <windows.h> | 17 #include <windows.h> |
18 | 18 |
19 #include <string> | 19 #include <string> |
20 #include <vector> | 20 #include <vector> |
21 | 21 |
22 #include "base/basictypes.h" | 22 #include "base/basictypes.h" |
23 #include "base/strings/stringprintf.h" | |
24 #include "base/strings/utf_string_conversions.h" | 23 #include "base/strings/utf_string_conversions.h" |
25 #include "client/crashpad_client.h" | 24 #include "client/crashpad_client.h" |
26 #include "gtest/gtest.h" | 25 #include "gtest/gtest.h" |
27 #include "test/win/win_child_process.h" | 26 #include "test/win/win_child_process.h" |
28 #include "util/thread/thread.h" | 27 #include "util/thread/thread.h" |
29 #include "util/win/address_types.h" | 28 #include "util/win/address_types.h" |
30 #include "util/win/registration_protocol_win.h" | 29 #include "util/win/registration_protocol_win.h" |
31 #include "util/win/scoped_handle.h" | 30 #include "util/win/scoped_handle.h" |
32 | 31 |
33 namespace crashpad { | 32 namespace crashpad { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 private: | 72 private: |
74 HANDLE server_ready_; // weak | 73 HANDLE server_ready_; // weak |
75 bool started_; | 74 bool started_; |
76 | 75 |
77 DISALLOW_COPY_AND_ASSIGN(TestDelegate); | 76 DISALLOW_COPY_AND_ASSIGN(TestDelegate); |
78 }; | 77 }; |
79 | 78 |
80 class ExceptionHandlerServerTest : public testing::Test { | 79 class ExceptionHandlerServerTest : public testing::Test { |
81 public: | 80 public: |
82 ExceptionHandlerServerTest() | 81 ExceptionHandlerServerTest() |
83 : pipe_name_("\\\\.\\pipe\\exception_handler_server_test_pipe_" + | 82 : server_(true), |
84 base::StringPrintf("%08x", GetCurrentProcessId())), | 83 pipe_name_(server_.CreatePipe()), |
85 server_ready_(CreateEvent(nullptr, false, false, nullptr)), | 84 server_ready_(CreateEvent(nullptr, false, false, nullptr)), |
86 delegate_(server_ready_.get()), | 85 delegate_(server_ready_.get()), |
87 server_(pipe_name_, true), | |
88 server_thread_(&server_, &delegate_) {} | 86 server_thread_(&server_, &delegate_) {} |
89 | 87 |
90 TestDelegate& delegate() { return delegate_; } | 88 TestDelegate& delegate() { return delegate_; } |
91 ExceptionHandlerServer& server() { return server_; } | 89 ExceptionHandlerServer& server() { return server_; } |
92 Thread& server_thread() { return server_thread_; } | 90 Thread& server_thread() { return server_thread_; } |
93 const std::string& pipe_name() const { return pipe_name_; } | 91 const std::wstring& pipe_name() const { return pipe_name_; } |
94 | 92 |
95 private: | 93 private: |
96 std::string pipe_name_; | 94 ExceptionHandlerServer server_; |
| 95 std::wstring pipe_name_; |
97 ScopedKernelHANDLE server_ready_; | 96 ScopedKernelHANDLE server_ready_; |
98 TestDelegate delegate_; | 97 TestDelegate delegate_; |
99 ExceptionHandlerServer server_; | |
100 RunServerThread server_thread_; | 98 RunServerThread server_thread_; |
101 | 99 |
102 DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerServerTest); | 100 DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerServerTest); |
103 }; | 101 }; |
104 | 102 |
105 // During destruction, ensures that the server is stopped and the background | 103 // During destruction, ensures that the server is stopped and the background |
106 // thread joined. | 104 // thread joined. |
107 class ScopedStopServerAndJoinThread { | 105 class ScopedStopServerAndJoinThread { |
108 public: | 106 public: |
109 ScopedStopServerAndJoinThread(ExceptionHandlerServer* server, Thread* thread) | 107 ScopedStopServerAndJoinThread(ExceptionHandlerServer* server, Thread* thread) |
(...skipping 18 matching lines...) Expand all Loading... |
128 &server(), &server_thread()); | 126 &server(), &server_thread()); |
129 ASSERT_NO_FATAL_FAILURE(delegate().WaitForStart()); | 127 ASSERT_NO_FATAL_FAILURE(delegate().WaitForStart()); |
130 } | 128 } |
131 | 129 |
132 TEST_F(ExceptionHandlerServerTest, StopWhileConnected) { | 130 TEST_F(ExceptionHandlerServerTest, StopWhileConnected) { |
133 server_thread().Start(); | 131 server_thread().Start(); |
134 ScopedStopServerAndJoinThread scoped_stop_server_and_join_thread( | 132 ScopedStopServerAndJoinThread scoped_stop_server_and_join_thread( |
135 &server(), &server_thread()); | 133 &server(), &server_thread()); |
136 ASSERT_NO_FATAL_FAILURE(delegate().WaitForStart()); | 134 ASSERT_NO_FATAL_FAILURE(delegate().WaitForStart()); |
137 CrashpadClient client; | 135 CrashpadClient client; |
138 client.SetHandlerIPCPipe(base::UTF8ToUTF16(pipe_name())); | 136 client.SetHandlerIPCPipe(pipe_name()); |
139 // Leaving this scope causes the server to be stopped, while the connection | 137 // Leaving this scope causes the server to be stopped, while the connection |
140 // is still open. | 138 // is still open. |
141 } | 139 } |
142 | 140 |
143 std::string ReadString(FileHandle handle) { | 141 std::wstring ReadWString(FileHandle handle) { |
144 size_t length = 0; | 142 size_t length = 0; |
145 EXPECT_TRUE(LoggingReadFile(handle, &length, sizeof(length))); | 143 EXPECT_TRUE(LoggingReadFile(handle, &length, sizeof(length))); |
146 scoped_ptr<char[]> buffer(new char[length]); | 144 std::wstring str(length, L'\0'); |
147 EXPECT_TRUE(LoggingReadFile(handle, &buffer[0], length)); | 145 if (length > 0) { |
148 return std::string(&buffer[0], length); | 146 EXPECT_TRUE(LoggingReadFile(handle, &str[0], length * sizeof(str[0]))); |
| 147 } |
| 148 return str; |
149 } | 149 } |
150 | 150 |
151 void WriteString(FileHandle handle, const std::string& str) { | 151 void WriteWString(FileHandle handle, const std::wstring& str) { |
152 size_t length = str.size(); | 152 size_t length = str.size(); |
153 EXPECT_TRUE(LoggingWriteFile(handle, &length, sizeof(length))); | 153 EXPECT_TRUE(LoggingWriteFile(handle, &length, sizeof(length))); |
154 EXPECT_TRUE(LoggingWriteFile(handle, &str[0], length)); | 154 if (length > 0) { |
| 155 EXPECT_TRUE(LoggingWriteFile(handle, &str[0], length * sizeof(str[0]))); |
| 156 } |
155 } | 157 } |
156 | 158 |
157 class TestClient final : public WinChildProcess { | 159 class TestClient final : public WinChildProcess { |
158 public: | 160 public: |
159 TestClient() : WinChildProcess() {} | 161 TestClient() : WinChildProcess() {} |
160 | 162 |
161 ~TestClient() {} | 163 ~TestClient() {} |
162 | 164 |
163 private: | 165 private: |
164 int Run() override { | 166 int Run() override { |
165 std::wstring pipe_name = base::UTF8ToUTF16(ReadString(ReadPipeHandle())); | 167 std::wstring pipe_name = ReadWString(ReadPipeHandle()); |
166 CrashpadClient client; | 168 CrashpadClient client; |
167 if (!client.SetHandlerIPCPipe(pipe_name)) { | 169 if (!client.SetHandlerIPCPipe(pipe_name)) { |
168 ADD_FAILURE(); | 170 ADD_FAILURE(); |
169 return EXIT_FAILURE; | 171 return EXIT_FAILURE; |
170 } | 172 } |
171 if (!client.UseHandler()) { | 173 if (!client.UseHandler()) { |
172 ADD_FAILURE(); | 174 ADD_FAILURE(); |
173 return EXIT_FAILURE; | 175 return EXIT_FAILURE; |
174 } | 176 } |
175 WriteString(WritePipeHandle(), "OK"); | 177 WriteWString(WritePipeHandle(), L"OK"); |
176 return EXIT_SUCCESS; | 178 return EXIT_SUCCESS; |
177 } | 179 } |
178 | 180 |
179 DISALLOW_COPY_AND_ASSIGN(TestClient); | 181 DISALLOW_COPY_AND_ASSIGN(TestClient); |
180 }; | 182 }; |
181 | 183 |
182 TEST_F(ExceptionHandlerServerTest, MultipleConnections) { | 184 TEST_F(ExceptionHandlerServerTest, MultipleConnections) { |
183 WinChildProcess::EntryPoint<TestClient>(); | 185 WinChildProcess::EntryPoint<TestClient>(); |
184 | 186 |
185 scoped_ptr<WinChildProcess::Handles> handles_1 = WinChildProcess::Launch(); | 187 scoped_ptr<WinChildProcess::Handles> handles_1 = WinChildProcess::Launch(); |
186 scoped_ptr<WinChildProcess::Handles> handles_2 = WinChildProcess::Launch(); | 188 scoped_ptr<WinChildProcess::Handles> handles_2 = WinChildProcess::Launch(); |
187 scoped_ptr<WinChildProcess::Handles> handles_3 = WinChildProcess::Launch(); | 189 scoped_ptr<WinChildProcess::Handles> handles_3 = WinChildProcess::Launch(); |
188 | 190 |
189 // Must ensure the delegate outlasts the server. | 191 // Must ensure the delegate outlasts the server. |
190 { | 192 { |
191 server_thread().Start(); | 193 server_thread().Start(); |
192 ScopedStopServerAndJoinThread scoped_stop_server_and_join_thread( | 194 ScopedStopServerAndJoinThread scoped_stop_server_and_join_thread( |
193 &server(), &server_thread()); | 195 &server(), &server_thread()); |
194 ASSERT_NO_FATAL_FAILURE(delegate().WaitForStart()); | 196 ASSERT_NO_FATAL_FAILURE(delegate().WaitForStart()); |
195 | 197 |
196 // Tell all the children where to connect. | 198 // Tell all the children where to connect. |
197 WriteString(handles_1->write.get(), pipe_name()); | 199 WriteWString(handles_1->write.get(), pipe_name()); |
198 WriteString(handles_2->write.get(), pipe_name()); | 200 WriteWString(handles_2->write.get(), pipe_name()); |
199 WriteString(handles_3->write.get(), pipe_name()); | 201 WriteWString(handles_3->write.get(), pipe_name()); |
200 | 202 |
201 ASSERT_EQ("OK", ReadString(handles_3->read.get())); | 203 ASSERT_EQ(L"OK", ReadWString(handles_3->read.get())); |
202 ASSERT_EQ("OK", ReadString(handles_2->read.get())); | 204 ASSERT_EQ(L"OK", ReadWString(handles_2->read.get())); |
203 ASSERT_EQ("OK", ReadString(handles_1->read.get())); | 205 ASSERT_EQ(L"OK", ReadWString(handles_1->read.get())); |
204 } | 206 } |
205 } | 207 } |
206 | 208 |
207 } // namespace | 209 } // namespace |
208 } // namespace test | 210 } // namespace test |
209 } // namespace crashpad | 211 } // namespace crashpad |
OLD | NEW |