Commit f50e9b22 authored by mseaborn@chromium.org's avatar mseaborn@chromium.org

NaCl: Split the debug exception handler thread into a separate file

This is in preparation for changing nacl_process_host.cc to reuse this
code instead of having its own copy in DebugContext.  This needs to go
into chrome/common rather than chrome/nacl so that
nacl_process_host.cc can #include it under the checkdeps rules.

This changes the code to use PostTask() instead of PostDelayedTask().

BUG=http://code.google.com/p/nativeclient/issues/detail?id=2618
TEST=run_inbrowser_exception_test in nacl_integration


Review URL: http://codereview.chromium.org/10211007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133851 0039d316-1c4b-4281-b951-d872f2087c98
parent 2b814977
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/nacl_debug_exception_handler_win.h"
#include "base/process_util.h"
#include "base/threading/platform_thread.h"
#include "native_client/src/trusted/service_runtime/win/debug_exception_handler.h"
namespace {
class DebugExceptionHandler : public base::PlatformThread::Delegate {
public:
DebugExceptionHandler(int32 pid,
base::MessageLoopProxy* message_loop,
const base::Closure& on_connected)
: pid_(pid), message_loop_(message_loop), on_connected_(on_connected) {
}
virtual void ThreadMain() OVERRIDE {
// In the Windows API, the set of processes being debugged is
// thread-local, so we have to attach to the process (using
// DebugActiveProcess()) on the same thread on which
// NaClDebugLoop() receives debug events for the process.
BOOL attached = false;
base::ProcessHandle process_handle = base::kNullProcessHandle;
if (!base::OpenProcessHandleWithAccess(
pid_,
base::kProcessAccessQueryInformation |
base::kProcessAccessSuspendResume |
base::kProcessAccessTerminate |
base::kProcessAccessVMOperation |
base::kProcessAccessVMRead |
base::kProcessAccessVMWrite |
base::kProcessAccessWaitForTermination,
&process_handle)) {
LOG(ERROR) << "Failed to get process handle";
} else {
attached = DebugActiveProcess(pid_);
if (!attached) {
LOG(ERROR) << "Failed to connect to the process";
}
}
// At the moment we do not say in the reply whether attaching as a
// debugger succeeded. In the future, when we attach on demand
// when an exception handler is first registered, we can make the
// NaCl syscall indicate whether attaching succeeded.
message_loop_->PostTask(FROM_HERE, on_connected_);
if (attached) {
DWORD exit_code;
NaClDebugLoop(process_handle, &exit_code);
}
if (process_handle != base::kNullProcessHandle) {
base::CloseProcessHandle(process_handle);
}
delete this;
}
private:
int32 pid_;
base::MessageLoopProxy* message_loop_;
base::Closure on_connected_;
DISALLOW_COPY_AND_ASSIGN(DebugExceptionHandler);
};
} // namespace
void NaClStartDebugExceptionHandlerThread(int32 nacl_process_id,
base::MessageLoopProxy* message_loop,
const base::Closure& on_connected) {
// The new PlatformThread will take ownership of the
// DebugExceptionHandler object, which will delete itself on exit.
DebugExceptionHandler* handler = new DebugExceptionHandler(
nacl_process_id, message_loop, on_connected);
if (!base::PlatformThread::CreateNonJoinable(0, handler)) {
on_connected.Run();
delete handler;
}
}
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_COMMON_NACL_DEBUG_EXCEPTION_HANDLER_WIN_H_
#define CHROME_COMMON_NACL_DEBUG_EXCEPTION_HANDLER_WIN_H_
#pragma once
#include "base/callback.h"
#include "base/message_loop.h"
void NaClStartDebugExceptionHandlerThread(int32 nacl_process_id,
base::MessageLoopProxy* message_loop,
const base::Closure& on_connected);
#endif // CHROME_COMMON_NACL_DEBUG_EXCEPTION_HANDLER_WIN_H_
...@@ -107,6 +107,7 @@ ...@@ -107,6 +107,7 @@
], ],
'sources': [ 'sources': [
'common/nacl_cmd_line.cc', 'common/nacl_cmd_line.cc',
'common/nacl_debug_exception_handler_win.cc',
'common/nacl_messages.cc', 'common/nacl_messages.cc',
'common/nacl_types.cc', 'common/nacl_types.cc',
'nacl/nacl_broker_listener.cc', 'nacl/nacl_broker_listener.cc',
......
...@@ -11,13 +11,12 @@ ...@@ -11,13 +11,12 @@
#include "base/message_loop_proxy.h" #include "base/message_loop_proxy.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/process_util.h" #include "base/process_util.h"
#include "base/threading/platform_thread.h"
#include "chrome/common/nacl_cmd_line.h" #include "chrome/common/nacl_cmd_line.h"
#include "chrome/common/nacl_debug_exception_handler_win.h"
#include "chrome/common/nacl_messages.h" #include "chrome/common/nacl_messages.h"
#include "content/common/sandbox_policy.h" #include "content/common/sandbox_policy.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
#include "ipc/ipc_switches.h" #include "ipc/ipc_switches.h"
#include "native_client/src/trusted/service_runtime/win/debug_exception_handler.h"
namespace { namespace {
...@@ -25,62 +24,6 @@ void SendReply(IPC::Channel* channel, int32 pid) { ...@@ -25,62 +24,6 @@ void SendReply(IPC::Channel* channel, int32 pid) {
channel->Send(new NaClProcessMsg_DebugExceptionHandlerLaunched(pid)); channel->Send(new NaClProcessMsg_DebugExceptionHandlerLaunched(pid));
} }
class DebugExceptionHandler : public base::PlatformThread::Delegate {
public:
DebugExceptionHandler(base::MessageLoopProxy* message_loop,
IPC::Channel* channel, int32 pid)
: message_loop_(message_loop), channel_(channel), pid_(pid) {
}
virtual void ThreadMain() OVERRIDE {
// In the Windows API, the set of processes being debugged is
// thread-local, so we have to attach to the process (using
// DebugActiveProcess()) on the same thread on which
// NaClDebugLoop() receives debug events for the process.
BOOL attached = false;
base::ProcessHandle process_handle = base::kNullProcessHandle;
if (!base::OpenProcessHandleWithAccess(
pid_,
base::kProcessAccessQueryInformation |
base::kProcessAccessSuspendResume |
base::kProcessAccessTerminate |
base::kProcessAccessVMOperation |
base::kProcessAccessVMRead |
base::kProcessAccessVMWrite |
base::kProcessAccessWaitForTermination,
&process_handle)) {
LOG(ERROR) << "Failed to get process handle";
} else {
attached = DebugActiveProcess(pid_);
if (!attached) {
LOG(ERROR) << "Failed to connect to the process";
}
}
// At the moment we do not say in the reply whether attaching as a
// debugger succeeded. In the future, when we attach on demand
// when an exception handler is first registered, we can make the
// NaCl syscall indicate whether attaching succeeded.
message_loop_->PostDelayedTask(FROM_HERE,
base::Bind(SendReply, channel_, pid_), base::TimeDelta());
if (attached) {
DWORD exit_code;
NaClDebugLoop(process_handle, &exit_code);
}
if (process_handle != base::kNullProcessHandle) {
base::CloseProcessHandle(process_handle);
}
delete this;
}
private:
base::MessageLoopProxy* message_loop_;
IPC::Channel* channel_;
int32 pid_;
DISALLOW_COPY_AND_ASSIGN(DebugExceptionHandler);
};
} // namespace } // namespace
NaClBrokerListener::NaClBrokerListener() NaClBrokerListener::NaClBrokerListener()
...@@ -156,14 +99,9 @@ void NaClBrokerListener::OnLaunchLoaderThroughBroker( ...@@ -156,14 +99,9 @@ void NaClBrokerListener::OnLaunchLoaderThroughBroker(
} }
void NaClBrokerListener::OnLaunchDebugExceptionHandler(int32 pid) { void NaClBrokerListener::OnLaunchDebugExceptionHandler(int32 pid) {
// The new PlatformThread will take ownership of the base::Closure reply_sender(base::Bind(SendReply, channel_.get(), pid));
// DebugExceptionHandler object, which will delete itself on exit. NaClStartDebugExceptionHandlerThread(pid, base::MessageLoopProxy::current(),
DebugExceptionHandler* handler = new DebugExceptionHandler( reply_sender);
base::MessageLoopProxy::current(), channel_.get(), pid);
if (!base::PlatformThread::CreateNonJoinable(0, handler)) {
SendReply(channel_.get(), pid);
delete handler;
}
} }
void NaClBrokerListener::OnStopBroker() { void NaClBrokerListener::OnStopBroker() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment