| 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/files/file_path.h" |   19 #include "base/files/file_path.h" | 
|   20 #include "base/strings/stringprintf.h" |  | 
|   21 #include "base/strings/string16.h" |   20 #include "base/strings/string16.h" | 
|   22 #include "base/strings/utf_string_conversions.h" |   21 #include "base/strings/utf_string_conversions.h" | 
|   23 #include "client/crashpad_client.h" |   22 #include "client/crashpad_client.h" | 
|   24 #include "gtest/gtest.h" |   23 #include "gtest/gtest.h" | 
|   25 #include "snapshot/win/process_snapshot_win.h" |   24 #include "snapshot/win/process_snapshot_win.h" | 
|   26 #include "test/paths.h" |   25 #include "test/paths.h" | 
|   27 #include "test/win/child_launcher.h" |   26 #include "test/win/child_launcher.h" | 
|   28 #include "util/file/file_io.h" |   27 #include "util/file/file_io.h" | 
|   29 #include "util/thread/thread.h" |   28 #include "util/thread/thread.h" | 
|   30 #include "util/win/exception_handler_server.h" |   29 #include "util/win/exception_handler_server.h" | 
|   31 #include "util/win/registration_protocol_win.h" |   30 #include "util/win/registration_protocol_win.h" | 
|   32 #include "util/win/scoped_handle.h" |   31 #include "util/win/scoped_handle.h" | 
|   33 #include "util/win/scoped_process_suspend.h" |   32 #include "util/win/scoped_process_suspend.h" | 
|   34  |   33  | 
|   35 namespace crashpad { |   34 namespace crashpad { | 
|   36 namespace test { |   35 namespace test { | 
|   37 namespace { |   36 namespace { | 
|   38  |   37  | 
|   39 // Runs the ExceptionHandlerServer on a background thread. |   38 // Runs the ExceptionHandlerServer on a background thread. | 
|   40 class RunServerThread : public Thread { |   39 class RunServerThread : public Thread { | 
|   41  public: |   40  public: | 
|   42   // Instantiates a thread which will invoke server->Run(delegate, pipe_name); |   41   // Instantiates a thread which will invoke server->Run(delegate); | 
|   43   RunServerThread(ExceptionHandlerServer* server, |   42   RunServerThread(ExceptionHandlerServer* server, | 
|   44                   ExceptionHandlerServer::Delegate* delegate) |   43                   ExceptionHandlerServer::Delegate* delegate) | 
|   45       : server_(server), delegate_(delegate) {} |   44       : server_(server), delegate_(delegate) {} | 
|   46   ~RunServerThread() override {} |   45   ~RunServerThread() override {} | 
|   47  |   46  | 
|   48  private: |   47  private: | 
|   49   // Thread: |   48   // Thread: | 
|   50   void ThreadMain() override { server_->Run(delegate_); } |   49   void ThreadMain() override { server_->Run(delegate_); } | 
|   51  |   50  | 
|   52   ExceptionHandlerServer* server_; |   51   ExceptionHandlerServer* server_; | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  115  private: |  114  private: | 
|  116   HANDLE server_ready_;  // weak |  115   HANDLE server_ready_;  // weak | 
|  117   HANDLE completed_test_event_;  // weak |  116   HANDLE completed_test_event_;  // weak | 
|  118   WinVMAddress break_near_; |  117   WinVMAddress break_near_; | 
|  119  |  118  | 
|  120   DISALLOW_COPY_AND_ASSIGN(CrashingDelegate); |  119   DISALLOW_COPY_AND_ASSIGN(CrashingDelegate); | 
|  121 }; |  120 }; | 
|  122  |  121  | 
|  123 void TestCrashingChild(const base::string16& directory_modification) { |  122 void TestCrashingChild(const base::string16& directory_modification) { | 
|  124   // Set up the registration server on a background thread. |  123   // Set up the registration server on a background thread. | 
|  125   std::string pipe_name = "\\\\.\\pipe\\handler_test_pipe_" + |  | 
|  126                           base::StringPrintf("%08x", GetCurrentProcessId()); |  | 
|  127   ScopedKernelHANDLE server_ready(CreateEvent(nullptr, false, false, nullptr)); |  124   ScopedKernelHANDLE server_ready(CreateEvent(nullptr, false, false, nullptr)); | 
|  128   ScopedKernelHANDLE completed(CreateEvent(nullptr, false, false, nullptr)); |  125   ScopedKernelHANDLE completed(CreateEvent(nullptr, false, false, nullptr)); | 
|  129   CrashingDelegate delegate(server_ready.get(), completed.get()); |  126   CrashingDelegate delegate(server_ready.get(), completed.get()); | 
|  130  |  127  | 
|  131   ExceptionHandlerServer exception_handler_server(pipe_name, true); |  128   ExceptionHandlerServer exception_handler_server(true); | 
 |  129   std::wstring pipe_name = exception_handler_server.CreatePipe(); | 
|  132   RunServerThread server_thread(&exception_handler_server, &delegate); |  130   RunServerThread server_thread(&exception_handler_server, &delegate); | 
|  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       &exception_handler_server, &server_thread); |  133       &exception_handler_server, &server_thread); | 
|  136  |  134  | 
|  137   WaitForSingleObject(server_ready.get(), INFINITE); |  135   WaitForSingleObject(server_ready.get(), INFINITE); | 
|  138  |  136  | 
|  139   // Spawn a child process, passing it the pipe name to connect to. |  137   // Spawn a child process, passing it the pipe name to connect to. | 
|  140   base::FilePath test_executable = Paths::Executable(); |  138   base::FilePath test_executable = Paths::Executable(); | 
|  141   std::wstring child_test_executable = |  139   std::wstring child_test_executable = | 
|  142       test_executable.DirName() |  140       test_executable.DirName() | 
|  143           .Append(directory_modification) |  141           .Append(directory_modification) | 
|  144           .Append(test_executable.BaseName().RemoveFinalExtension().value() + |  142           .Append(test_executable.BaseName().RemoveFinalExtension().value() + | 
|  145                   L"_crashing_child.exe") |  143                   L"_crashing_child.exe") | 
|  146           .value(); |  144           .value(); | 
|  147   ChildLauncher child(child_test_executable, base::UTF8ToUTF16(pipe_name)); |  145   ChildLauncher child(child_test_executable, pipe_name); | 
|  148   child.Start(); |  146   child.Start(); | 
|  149  |  147  | 
|  150   // The child tells us (approximately) where it will crash. |  148   // The child tells us (approximately) where it will crash. | 
|  151   WinVMAddress break_near_address; |  149   WinVMAddress break_near_address; | 
|  152   LoggingReadFile(child.stdout_read_handle(), |  150   LoggingReadFile(child.stdout_read_handle(), | 
|  153                   &break_near_address, |  151                   &break_near_address, | 
|  154                   sizeof(break_near_address)); |  152                   sizeof(break_near_address)); | 
|  155   delegate.set_break_near(break_near_address); |  153   delegate.set_break_near(break_near_address); | 
|  156  |  154  | 
|  157   // Wait for the child to crash and the exception information to be validated. |  155   // Wait for the child to crash and the exception information to be validated. | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  217   HANDLE server_ready_;  // weak |  215   HANDLE server_ready_;  // weak | 
|  218   HANDLE completed_test_event_;  // weak |  216   HANDLE completed_test_event_;  // weak | 
|  219   WinVMAddress dump_near_; |  217   WinVMAddress dump_near_; | 
|  220  |  218  | 
|  221   DISALLOW_COPY_AND_ASSIGN(SimulateDelegate); |  219   DISALLOW_COPY_AND_ASSIGN(SimulateDelegate); | 
|  222 }; |  220 }; | 
|  223  |  221  | 
|  224 void TestDumpWithoutCrashingChild( |  222 void TestDumpWithoutCrashingChild( | 
|  225     const base::string16& directory_modification) { |  223     const base::string16& directory_modification) { | 
|  226   // Set up the registration server on a background thread. |  224   // Set up the registration server on a background thread. | 
|  227   std::string pipe_name = "\\\\.\\pipe\\handler_test_pipe_" + |  | 
|  228                           base::StringPrintf("%08x", GetCurrentProcessId()); |  | 
|  229   ScopedKernelHANDLE server_ready(CreateEvent(nullptr, false, false, nullptr)); |  225   ScopedKernelHANDLE server_ready(CreateEvent(nullptr, false, false, nullptr)); | 
|  230   ScopedKernelHANDLE completed(CreateEvent(nullptr, false, false, nullptr)); |  226   ScopedKernelHANDLE completed(CreateEvent(nullptr, false, false, nullptr)); | 
|  231   SimulateDelegate delegate(server_ready.get(), completed.get()); |  227   SimulateDelegate delegate(server_ready.get(), completed.get()); | 
|  232  |  228  | 
|  233   ExceptionHandlerServer exception_handler_server(pipe_name, true); |  229   ExceptionHandlerServer exception_handler_server(true); | 
 |  230   std::wstring pipe_name = exception_handler_server.CreatePipe(); | 
|  234   RunServerThread server_thread(&exception_handler_server, &delegate); |  231   RunServerThread server_thread(&exception_handler_server, &delegate); | 
|  235   server_thread.Start(); |  232   server_thread.Start(); | 
|  236   ScopedStopServerAndJoinThread scoped_stop_server_and_join_thread( |  233   ScopedStopServerAndJoinThread scoped_stop_server_and_join_thread( | 
|  237       &exception_handler_server, &server_thread); |  234       &exception_handler_server, &server_thread); | 
|  238  |  235  | 
|  239   WaitForSingleObject(server_ready.get(), INFINITE); |  236   WaitForSingleObject(server_ready.get(), INFINITE); | 
|  240  |  237  | 
|  241   // Spawn a child process, passing it the pipe name to connect to. |  238   // Spawn a child process, passing it the pipe name to connect to. | 
|  242   base::FilePath test_executable = Paths::Executable(); |  239   base::FilePath test_executable = Paths::Executable(); | 
|  243   std::wstring child_test_executable = |  240   std::wstring child_test_executable = | 
|  244       test_executable.DirName() |  241       test_executable.DirName() | 
|  245           .Append(directory_modification) |  242           .Append(directory_modification) | 
|  246           .Append(test_executable.BaseName().RemoveFinalExtension().value() + |  243           .Append(test_executable.BaseName().RemoveFinalExtension().value() + | 
|  247                   L"_dump_without_crashing.exe") |  244                   L"_dump_without_crashing.exe") | 
|  248           .value(); |  245           .value(); | 
|  249   ChildLauncher child(child_test_executable, base::UTF8ToUTF16(pipe_name)); |  246   ChildLauncher child(child_test_executable, pipe_name); | 
|  250   child.Start(); |  247   child.Start(); | 
|  251  |  248  | 
|  252   // The child tells us (approximately) where it will capture a dump. |  249   // The child tells us (approximately) where it will capture a dump. | 
|  253   WinVMAddress dump_near_address; |  250   WinVMAddress dump_near_address; | 
|  254   LoggingReadFile(child.stdout_read_handle(), |  251   LoggingReadFile(child.stdout_read_handle(), | 
|  255                   &dump_near_address, |  252                   &dump_near_address, | 
|  256                   sizeof(dump_near_address)); |  253                   sizeof(dump_near_address)); | 
|  257   delegate.set_dump_near(dump_near_address); |  254   delegate.set_dump_near(dump_near_address); | 
|  258  |  255  | 
|  259   // Wait for the child to crash and the exception information to be validated. |  256   // Wait for the child to crash and the exception information to be validated. | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  270   TestDumpWithoutCrashingChild(FILE_PATH_LITERAL("..\\..\\out\\Debug")); |  267   TestDumpWithoutCrashingChild(FILE_PATH_LITERAL("..\\..\\out\\Debug")); | 
|  271 #else |  268 #else | 
|  272   TestDumpWithoutCrashingChild(FILE_PATH_LITERAL("..\\..\\out\\Release")); |  269   TestDumpWithoutCrashingChild(FILE_PATH_LITERAL("..\\..\\out\\Release")); | 
|  273 #endif |  270 #endif | 
|  274 } |  271 } | 
|  275 #endif  // ARCH_CPU_64_BITS |  272 #endif  // ARCH_CPU_64_BITS | 
|  276  |  273  | 
|  277 }  // namespace |  274 }  // namespace | 
|  278 }  // namespace test |  275 }  // namespace test | 
|  279 }  // namespace crashpad |  276 }  // namespace crashpad | 
| OLD | NEW |