OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/common/nacl_debug_exception_handler_win.h" |
| 6 |
| 7 #include "base/process_util.h" |
| 8 #include "base/threading/platform_thread.h" |
| 9 #include "native_client/src/trusted/service_runtime/win/debug_exception_handler.
h" |
| 10 |
| 11 namespace { |
| 12 |
| 13 class DebugExceptionHandler : public base::PlatformThread::Delegate { |
| 14 public: |
| 15 DebugExceptionHandler(int32 pid, |
| 16 base::MessageLoopProxy* message_loop, |
| 17 base::Closure& on_connected) |
| 18 : pid_(pid), message_loop_(message_loop), on_connected_(on_connected) { |
| 19 } |
| 20 |
| 21 virtual void ThreadMain() OVERRIDE { |
| 22 // In the Windows API, the set of processes being debugged is |
| 23 // thread-local, so we have to attach to the process (using |
| 24 // DebugActiveProcess()) on the same thread on which |
| 25 // NaClDebugLoop() receives debug events for the process. |
| 26 BOOL attached = false; |
| 27 base::ProcessHandle process_handle = base::kNullProcessHandle; |
| 28 if (!base::OpenProcessHandleWithAccess( |
| 29 pid_, |
| 30 base::kProcessAccessQueryInformation | |
| 31 base::kProcessAccessSuspendResume | |
| 32 base::kProcessAccessTerminate | |
| 33 base::kProcessAccessVMOperation | |
| 34 base::kProcessAccessVMRead | |
| 35 base::kProcessAccessVMWrite | |
| 36 base::kProcessAccessWaitForTermination, |
| 37 &process_handle)) { |
| 38 LOG(ERROR) << "Failed to get process handle"; |
| 39 } else { |
| 40 attached = DebugActiveProcess(pid_); |
| 41 if (!attached) { |
| 42 LOG(ERROR) << "Failed to connect to the process"; |
| 43 } |
| 44 } |
| 45 // At the moment we do not say in the reply whether attaching as a |
| 46 // debugger succeeded. In the future, when we attach on demand |
| 47 // when an exception handler is first registered, we can make the |
| 48 // NaCl syscall indicate whether attaching succeeded. |
| 49 message_loop_->PostTask(FROM_HERE, on_connected_); |
| 50 |
| 51 if (attached) { |
| 52 DWORD exit_code; |
| 53 NaClDebugLoop(process_handle, &exit_code); |
| 54 } |
| 55 if (process_handle != base::kNullProcessHandle) { |
| 56 base::CloseProcessHandle(process_handle); |
| 57 } |
| 58 delete this; |
| 59 } |
| 60 |
| 61 private: |
| 62 int32 pid_; |
| 63 base::MessageLoopProxy* message_loop_; |
| 64 base::Closure on_connected_; |
| 65 |
| 66 DISALLOW_COPY_AND_ASSIGN(DebugExceptionHandler); |
| 67 }; |
| 68 |
| 69 } // namespace |
| 70 |
| 71 void NaClStartDebugExceptionHandlerThread(int32 nacl_process_id, |
| 72 base::MessageLoopProxy* message_loop, |
| 73 base::Closure& on_connected) { |
| 74 // The new PlatformThread will take ownership of the |
| 75 // DebugExceptionHandler object, which will delete itself on exit. |
| 76 DebugExceptionHandler* handler = new DebugExceptionHandler( |
| 77 nacl_process_id, message_loop, on_connected); |
| 78 if (!base::PlatformThread::CreateNonJoinable(0, handler)) { |
| 79 on_connected.Run(); |
| 80 delete handler; |
| 81 } |
| 82 } |
OLD | NEW |