summaryrefslogtreecommitdiffstats
path: root/chrome/nacl
diff options
context:
space:
mode:
authormseaborn@chromium.org <mseaborn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-24 18:11:38 +0000
committermseaborn@chromium.org <mseaborn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-24 18:11:38 +0000
commitfb335fe0cf9bce0888dd72b84359e83cc5b08991 (patch)
treeda4a9a8ade30b26eac8d128e2eafe72fc4823b86 /chrome/nacl
parent2ded2ee298c09a45032fe6cdf8349370f01003d3 (diff)
downloadchromium_src-fb335fe0cf9bce0888dd72b84359e83cc5b08991.zip
chromium_src-fb335fe0cf9bce0888dd72b84359e83cc5b08991.tar.gz
chromium_src-fb335fe0cf9bce0888dd72b84359e83cc5b08991.tar.bz2
NaCl: Make hardware exception handling work on 64-bit Windows
In order to support untrusted hardware exception handling on 64-bit Windows, we need to have a 64-bit process attach as a debugger to the 64-bit NaCl loader process, so we extend the NaCl broker process to do this. The new code in nacl_broker_listener.cc for attaching a 64-bit debugger is similar to the 32-bit code in nacl_process_host.cc. I intend to unify the two in a later change. BUG=http://code.google.com/p/nativeclient/issues/detail?id=2651 TEST=run_inbrowser_exception_test in nacl_integration Review URL: https://chromiumcodereview.appspot.com/9835003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@128764 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/nacl')
-rw-r--r--chrome/nacl/nacl_broker_listener.cc83
-rw-r--r--chrome/nacl/nacl_broker_listener.h1
2 files changed, 83 insertions, 1 deletions
diff --git a/chrome/nacl/nacl_broker_listener.cc b/chrome/nacl/nacl_broker_listener.cc
index 32fc9ef..97346e9 100644
--- a/chrome/nacl/nacl_broker_listener.cc
+++ b/chrome/nacl/nacl_broker_listener.cc
@@ -1,19 +1,87 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// 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/nacl/nacl_broker_listener.h"
#include "base/base_switches.h"
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/message_loop.h"
+#include "base/message_loop_proxy.h"
#include "base/path_service.h"
#include "base/process_util.h"
+#include "base/threading/platform_thread.h"
#include "chrome/common/nacl_cmd_line.h"
#include "chrome/common/nacl_messages.h"
#include "content/common/sandbox_policy.h"
#include "content/public/common/content_switches.h"
#include "ipc/ipc_switches.h"
+#include "native_client/src/trusted/service_runtime/win/debug_exception_handler.h"
+
+namespace {
+
+void SendReply(IPC::Channel* channel, int32 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
NaClBrokerListener::NaClBrokerListener()
: browser_handle_(base::kNullProcessHandle) {
@@ -43,6 +111,8 @@ bool NaClBrokerListener::OnMessageReceived(const IPC::Message& msg) {
IPC_BEGIN_MESSAGE_MAP(NaClBrokerListener, msg)
IPC_MESSAGE_HANDLER(NaClProcessMsg_LaunchLoaderThroughBroker,
OnLaunchLoaderThroughBroker)
+ IPC_MESSAGE_HANDLER(NaClProcessMsg_LaunchDebugExceptionHandler,
+ OnLaunchDebugExceptionHandler)
IPC_MESSAGE_HANDLER(NaClProcessMsg_StopBroker, OnStopBroker)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -85,6 +155,17 @@ void NaClBrokerListener::OnLaunchLoaderThroughBroker(
loader_handle_in_browser));
}
+void NaClBrokerListener::OnLaunchDebugExceptionHandler(int32 pid) {
+ // The new PlatformThread will take ownership of the
+ // DebugExceptionHandler object, which will delete itself on exit.
+ DebugExceptionHandler* handler = new DebugExceptionHandler(
+ base::MessageLoopProxy::current(), channel_.get(), pid);
+ if (!base::PlatformThread::CreateNonJoinable(0, handler)) {
+ SendReply(channel_.get(), pid);
+ delete handler;
+ }
+}
+
void NaClBrokerListener::OnStopBroker() {
MessageLoop::current()->Quit();
}
diff --git a/chrome/nacl/nacl_broker_listener.h b/chrome/nacl/nacl_broker_listener.h
index e1c3dd7..dccf57c 100644
--- a/chrome/nacl/nacl_broker_listener.h
+++ b/chrome/nacl/nacl_broker_listener.h
@@ -27,6 +27,7 @@ class NaClBrokerListener : public IPC::Channel::Listener {
private:
void OnLaunchLoaderThroughBroker(const std::wstring& loader_channel_id);
+ void OnLaunchDebugExceptionHandler(int32 pid);
void OnStopBroker();
base::ProcessHandle browser_handle_;