1 // Copyright 2013 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 "components/nacl/common/nacl_debug_exception_handler_win.h" 6 7 #include "base/bind.h" 8 #include "base/threading/platform_thread.h" 9 #include "base/win/scoped_handle.h" 10 #include "native_client/src/trusted/service_runtime/win/debug_exception_handler.h" 11 12 namespace { 13 14 class DebugExceptionHandler : public base::PlatformThread::Delegate { 15 public: 16 DebugExceptionHandler(base::ProcessHandle nacl_process, 17 const std::string& startup_info, 18 base::MessageLoopProxy* message_loop, 19 const base::Callback<void(bool)>& on_connected) 20 : nacl_process_(nacl_process), 21 startup_info_(startup_info), 22 message_loop_(message_loop), 23 on_connected_(on_connected) { 24 } 25 26 virtual void ThreadMain() OVERRIDE { 27 // In the Windows API, the set of processes being debugged is 28 // thread-local, so we have to attach to the process (using 29 // DebugActiveProcess()) on the same thread on which 30 // NaClDebugExceptionHandlerRun() receives debug events for the 31 // process. 32 bool attached = false; 33 int pid = GetProcessId(nacl_process_); 34 if (pid == 0) { 35 LOG(ERROR) << "Invalid process handle"; 36 } else { 37 if (!DebugActiveProcess(pid)) { 38 LOG(ERROR) << "Failed to connect to the process"; 39 } else { 40 attached = true; 41 } 42 } 43 message_loop_->PostTask(FROM_HERE, base::Bind(on_connected_, attached)); 44 45 if (attached) { 46 NaClDebugExceptionHandlerRun( 47 nacl_process_, 48 reinterpret_cast<const void*>(startup_info_.data()), 49 startup_info_.size()); 50 } 51 delete this; 52 } 53 54 private: 55 base::win::ScopedHandle nacl_process_; 56 std::string startup_info_; 57 base::MessageLoopProxy* message_loop_; 58 base::Callback<void(bool)> on_connected_; 59 60 DISALLOW_COPY_AND_ASSIGN(DebugExceptionHandler); 61 }; 62 63 } // namespace 64 65 void NaClStartDebugExceptionHandlerThread( 66 base::ProcessHandle nacl_process, 67 const std::string& startup_info, 68 base::MessageLoopProxy* message_loop, 69 const base::Callback<void(bool)>& on_connected) { 70 // The new PlatformThread will take ownership of the 71 // DebugExceptionHandler object, which will delete itself on exit. 72 DebugExceptionHandler* handler = new DebugExceptionHandler( 73 nacl_process, startup_info, message_loop, on_connected); 74 if (!base::PlatformThread::CreateNonJoinable(0, handler)) { 75 on_connected.Run(false); 76 delete handler; 77 } 78 } 79