| 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 "snapshot/win/exception_snapshot_win.h" | 15 #include "snapshot/win/exception_snapshot_win.h" |
| 16 | 16 |
| 17 #include <string> | 17 #include <string> |
| 18 | 18 |
| 19 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
| 21 #include "client/crashpad_client.h" | 21 #include "client/crashpad_client.h" |
| 22 #include "gtest/gtest.h" | 22 #include "gtest/gtest.h" |
| 23 #include "snapshot/win/process_reader_win.h" | |
| 24 #include "snapshot/win/process_snapshot_win.h" | 23 #include "snapshot/win/process_snapshot_win.h" |
| 25 #include "test/win/win_child_process.h" | 24 #include "test/win/win_child_process.h" |
| 26 #include "util/thread/thread.h" | 25 #include "util/thread/thread.h" |
| 27 #include "util/win/exception_handler_server.h" | 26 #include "util/win/exception_handler_server.h" |
| 28 #include "util/win/registration_protocol_win.h" | 27 #include "util/win/registration_protocol_win.h" |
| 29 #include "util/win/scoped_handle.h" | 28 #include "util/win/scoped_handle.h" |
| 30 | 29 |
| 31 namespace crashpad { | 30 namespace crashpad { |
| 32 namespace test { | 31 namespace test { |
| 33 namespace { | 32 namespace { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 56 break_near_(nullptr) {} | 55 break_near_(nullptr) {} |
| 57 ~Delegate() override {} | 56 ~Delegate() override {} |
| 58 | 57 |
| 59 void set_break_near(void* break_near) { break_near_ = break_near; } | 58 void set_break_near(void* break_near) { break_near_ = break_near; } |
| 60 | 59 |
| 61 void ExceptionHandlerServerStarted() override { SetEvent(server_ready_); } | 60 void ExceptionHandlerServerStarted() override { SetEvent(server_ready_); } |
| 62 | 61 |
| 63 unsigned int ExceptionHandlerServerException( | 62 unsigned int ExceptionHandlerServerException( |
| 64 HANDLE process, | 63 HANDLE process, |
| 65 WinVMAddress exception_information_address) override { | 64 WinVMAddress exception_information_address) override { |
| 66 // Snapshot the process and exception. | |
| 67 ProcessReaderWin process_reader; | |
| 68 EXPECT_TRUE(process_reader.Initialize(process)); | |
| 69 if (HasFatalFailure()) | |
| 70 return 0xffffffff; | |
| 71 ExceptionInformation exception_information; | |
| 72 EXPECT_TRUE( | |
| 73 process_reader.ReadMemory(exception_information_address, | |
| 74 sizeof(exception_information), | |
| 75 &exception_information)); | |
| 76 if (HasFatalFailure()) | |
| 77 return 0xffffffff; | |
| 78 ProcessSnapshotWin snapshot; | 65 ProcessSnapshotWin snapshot; |
| 79 snapshot.Initialize(process); | 66 snapshot.Initialize(process); |
| 80 snapshot.InitializeException(exception_information.thread_id, | 67 snapshot.InitializeException(exception_information_address); |
| 81 exception_information.exception_pointers); | |
| 82 | 68 |
| 83 // Confirm the exception record was read correctly. | 69 // Confirm the exception record was read correctly. |
| 84 EXPECT_NE(snapshot.Exception()->ThreadID(), 0u); | 70 EXPECT_NE(snapshot.Exception()->ThreadID(), 0u); |
| 85 EXPECT_EQ(snapshot.Exception()->Exception(), EXCEPTION_BREAKPOINT); | 71 EXPECT_EQ(snapshot.Exception()->Exception(), EXCEPTION_BREAKPOINT); |
| 86 | 72 |
| 87 // Verify the exception happened at the expected location with a bit of | 73 // Verify the exception happened at the expected location with a bit of |
| 88 // slop space to allow for reading the current PC before the exception | 74 // slop space to allow for reading the current PC before the exception |
| 89 // happens. See CrashingChildProcess::Run(). | 75 // happens. See CrashingChildProcess::Run(). |
| 90 const uint64_t kAllowedOffset = 64; | 76 const uint64_t kAllowedOffset = 64; |
| 91 EXPECT_GT(snapshot.Exception()->ExceptionAddress(), | 77 EXPECT_GT(snapshot.Exception()->ExceptionAddress(), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 106 DISALLOW_COPY_AND_ASSIGN(Delegate); | 92 DISALLOW_COPY_AND_ASSIGN(Delegate); |
| 107 }; | 93 }; |
| 108 | 94 |
| 109 private: | 95 private: |
| 110 ScopedKernelHANDLE exception_happened_; | 96 ScopedKernelHANDLE exception_happened_; |
| 111 }; | 97 }; |
| 112 | 98 |
| 113 // Runs the ExceptionHandlerServer on a background thread. | 99 // Runs the ExceptionHandlerServer on a background thread. |
| 114 class RunServerThread : public Thread { | 100 class RunServerThread : public Thread { |
| 115 public: | 101 public: |
| 116 // Instantiates a thread which will invoke server->Run(pipe_name); | 102 // Instantiates a thread which will invoke server->Run(delegate, pipe_name); |
| 117 explicit RunServerThread(ExceptionHandlerServer* server, | 103 RunServerThread(ExceptionHandlerServer* server, |
| 118 const std::string& pipe_name) | 104 ExceptionHandlerServer::Delegate* delegate, |
| 119 : server_(server), pipe_name_(pipe_name) {} | 105 const std::string& pipe_name) |
| 106 : server_(server), delegate_(delegate), pipe_name_(pipe_name) {} |
| 120 ~RunServerThread() override {} | 107 ~RunServerThread() override {} |
| 121 | 108 |
| 122 private: | 109 private: |
| 123 // Thread: | 110 // Thread: |
| 124 void ThreadMain() override { server_->Run(pipe_name_); } | 111 void ThreadMain() override { server_->Run(delegate_, pipe_name_); } |
| 125 | 112 |
| 126 ExceptionHandlerServer* server_; | 113 ExceptionHandlerServer* server_; |
| 114 ExceptionHandlerServer::Delegate* delegate_; |
| 127 std::string pipe_name_; | 115 std::string pipe_name_; |
| 128 | 116 |
| 129 DISALLOW_COPY_AND_ASSIGN(RunServerThread); | 117 DISALLOW_COPY_AND_ASSIGN(RunServerThread); |
| 130 }; | 118 }; |
| 131 | 119 |
| 132 // During destruction, ensures that the server is stopped and the background | 120 // During destruction, ensures that the server is stopped and the background |
| 133 // thread joined. | 121 // thread joined. |
| 134 class ScopedStopServerAndJoinThread { | 122 class ScopedStopServerAndJoinThread { |
| 135 public: | 123 public: |
| 136 explicit ScopedStopServerAndJoinThread(ExceptionHandlerServer* server, | 124 ScopedStopServerAndJoinThread(ExceptionHandlerServer* server, Thread* thread) |
| 137 Thread* thread) | |
| 138 : server_(server), thread_(thread) {} | 125 : server_(server), thread_(thread) {} |
| 139 ~ScopedStopServerAndJoinThread() { | 126 ~ScopedStopServerAndJoinThread() { |
| 140 server_->Stop(); | 127 server_->Stop(); |
| 141 thread_->Join(); | 128 thread_->Join(); |
| 142 } | 129 } |
| 143 | 130 |
| 144 private: | 131 private: |
| 145 ExceptionHandlerServer* server_; | 132 ExceptionHandlerServer* server_; |
| 146 Thread* thread_; | 133 Thread* thread_; |
| 147 DISALLOW_COPY_AND_ASSIGN(ScopedStopServerAndJoinThread); | 134 DISALLOW_COPY_AND_ASSIGN(ScopedStopServerAndJoinThread); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 WinChildProcess::EntryPoint<CrashingChildProcess>(); | 179 WinChildProcess::EntryPoint<CrashingChildProcess>(); |
| 193 scoped_ptr<WinChildProcess::Handles> handle = WinChildProcess::Launch(); | 180 scoped_ptr<WinChildProcess::Handles> handle = WinChildProcess::Launch(); |
| 194 | 181 |
| 195 // Set up the registration server on a background thread. | 182 // Set up the registration server on a background thread. |
| 196 std::string pipe_name = "\\\\.\\pipe\\handler_test_pipe_" + | 183 std::string pipe_name = "\\\\.\\pipe\\handler_test_pipe_" + |
| 197 base::StringPrintf("%08x", GetCurrentProcessId()); | 184 base::StringPrintf("%08x", GetCurrentProcessId()); |
| 198 ScopedKernelHANDLE server_ready(CreateEvent(nullptr, false, false, nullptr)); | 185 ScopedKernelHANDLE server_ready(CreateEvent(nullptr, false, false, nullptr)); |
| 199 ScopedKernelHANDLE completed(CreateEvent(nullptr, false, false, nullptr)); | 186 ScopedKernelHANDLE completed(CreateEvent(nullptr, false, false, nullptr)); |
| 200 Delegate delegate(server_ready.get(), completed.get()); | 187 Delegate delegate(server_ready.get(), completed.get()); |
| 201 | 188 |
| 202 ExceptionHandlerServer exception_handler_server(&delegate); | 189 ExceptionHandlerServer exception_handler_server; |
| 203 RunServerThread server_thread(&exception_handler_server, pipe_name); | 190 RunServerThread server_thread( |
| 191 &exception_handler_server, &delegate, pipe_name); |
| 204 server_thread.Start(); | 192 server_thread.Start(); |
| 205 ScopedStopServerAndJoinThread scoped_stop_server_and_join_thread( | 193 ScopedStopServerAndJoinThread scoped_stop_server_and_join_thread( |
| 206 &exception_handler_server, &server_thread); | 194 &exception_handler_server, &server_thread); |
| 207 | 195 |
| 208 WaitForSingleObject(server_ready.get(), INFINITE); | 196 WaitForSingleObject(server_ready.get(), INFINITE); |
| 209 // Allow the child to continue and tell it where to connect to. | 197 // Allow the child to continue and tell it where to connect to. |
| 210 WriteString(handle->write.get(), pipe_name); | 198 WriteString(handle->write.get(), pipe_name); |
| 211 | 199 |
| 212 // The child tells us (approximately) where it will crash. | 200 // The child tells us (approximately) where it will crash. |
| 213 void* break_near_address; | 201 void* break_near_address; |
| 214 LoggingReadFile( | 202 LoggingReadFile( |
| 215 handle->read.get(), &break_near_address, sizeof(break_near_address)); | 203 handle->read.get(), &break_near_address, sizeof(break_near_address)); |
| 216 delegate.set_break_near(break_near_address); | 204 delegate.set_break_near(break_near_address); |
| 217 | 205 |
| 218 // Wait for the child to crash and the exception information to be validated. | 206 // Wait for the child to crash and the exception information to be validated. |
| 219 WaitForSingleObject(completed.get(), INFINITE); | 207 WaitForSingleObject(completed.get(), INFINITE); |
| 220 } | 208 } |
| 221 | 209 |
| 222 } // namespace | 210 } // namespace |
| 223 } // namespace test | 211 } // namespace test |
| 224 } // namespace crashpad | 212 } // namespace crashpad |
| OLD | NEW |