Home | History | Annotate | Download | only in common
      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