| 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 |