1a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "components/nacl/common/nacl_debug_exception_handler_win.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_handle.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/trusted/service_runtime/win/debug_exception_handler.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DebugExceptionHandler : public base::PlatformThread::Delegate { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DebugExceptionHandler(base::ProcessHandle nacl_process, 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& startup_info, 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MessageLoopProxy* message_loop, 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<void(bool)>& on_connected) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : nacl_process_(nacl_process), 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) startup_info_(startup_info), 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_(message_loop), 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) on_connected_(on_connected) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ThreadMain() OVERRIDE { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In the Windows API, the set of processes being debugged is 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread-local, so we have to attach to the process (using 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DebugActiveProcess()) on the same thread on which 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NaClDebugExceptionHandlerRun() receives debug events for the 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // process. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool attached = false; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pid = GetProcessId(nacl_process_); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pid == 0) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Invalid process handle"; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!DebugActiveProcess(pid)) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to connect to the process"; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attached = true; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_->PostTask(FROM_HERE, base::Bind(on_connected_, attached)); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (attached) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NaClDebugExceptionHandlerRun( 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nacl_process_, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const void*>(startup_info_.data()), 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) startup_info_.size()); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedHandle nacl_process_; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string startup_info_; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MessageLoopProxy* message_loop_; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Callback<void(bool)> on_connected_; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DebugExceptionHandler); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NaClStartDebugExceptionHandlerThread( 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle nacl_process, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& startup_info, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MessageLoopProxy* message_loop, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<void(bool)>& on_connected) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The new PlatformThread will take ownership of the 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DebugExceptionHandler object, which will delete itself on exit. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DebugExceptionHandler* handler = new DebugExceptionHandler( 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nacl_process, startup_info, message_loop, on_connected); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::PlatformThread::CreateNonJoinable(0, handler)) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) on_connected.Run(false); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete handler; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 79