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