summaryrefslogtreecommitdiffstats
path: root/chrome/browser/nacl_host
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/browser/nacl_host
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/browser/nacl_host')
-rw-r--r--chrome/browser/nacl_host/nacl_broker_host_win.cc10
-rw-r--r--chrome/browser/nacl_host/nacl_broker_host_win.h4
-rw-r--r--chrome/browser/nacl_host/nacl_broker_service_win.cc19
-rw-r--r--chrome/browser/nacl_host/nacl_broker_service_win.h13
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.cc79
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.h3
6 files changed, 90 insertions, 38 deletions
diff --git a/chrome/browser/nacl_host/nacl_broker_host_win.cc b/chrome/browser/nacl_host/nacl_broker_host_win.cc
index 92e1453..3df9731 100644
--- a/chrome/browser/nacl_host/nacl_broker_host_win.cc
+++ b/chrome/browser/nacl_host/nacl_broker_host_win.cc
@@ -54,6 +54,8 @@ bool NaClBrokerHost::OnMessageReceived(const IPC::Message& msg) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(NaClBrokerHost, msg)
IPC_MESSAGE_HANDLER(NaClProcessMsg_LoaderLaunched, OnLoaderLaunched)
+ IPC_MESSAGE_HANDLER(NaClProcessMsg_DebugExceptionHandlerLaunched,
+ OnDebugExceptionHandlerLaunched)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -70,6 +72,14 @@ void NaClBrokerHost::OnLoaderLaunched(const std::wstring& loader_channel_id,
NaClBrokerService::GetInstance()->OnLoaderLaunched(loader_channel_id, handle);
}
+bool NaClBrokerHost::LaunchDebugExceptionHandler(int32 pid) {
+ return process_->Send(new NaClProcessMsg_LaunchDebugExceptionHandler(pid));
+}
+
+void NaClBrokerHost::OnDebugExceptionHandlerLaunched(int32 pid) {
+ NaClBrokerService::GetInstance()->OnDebugExceptionHandlerLaunched(pid);
+}
+
void NaClBrokerHost::StopBroker() {
process_->Send(new NaClProcessMsg_StopBroker());
}
diff --git a/chrome/browser/nacl_host/nacl_broker_host_win.h b/chrome/browser/nacl_host/nacl_broker_host_win.h
index 3ea6a33..353badd 100644
--- a/chrome/browser/nacl_host/nacl_broker_host_win.h
+++ b/chrome/browser/nacl_host/nacl_broker_host_win.h
@@ -28,6 +28,8 @@ class NaClBrokerHost : public content::BrowserChildProcessHostDelegate {
// a Native Client loader process.
bool LaunchLoader(const std::wstring& loader_channel_id);
+ bool LaunchDebugExceptionHandler(int32 pid);
+
// Stop the broker process.
void StopBroker();
@@ -35,6 +37,8 @@ class NaClBrokerHost : public content::BrowserChildProcessHostDelegate {
// Handler for NaClProcessMsg_LoaderLaunched message
void OnLoaderLaunched(const std::wstring& loader_channel_id,
base::ProcessHandle handle);
+ // Handler for NaClProcessMsg_DebugExceptionHandlerLaunched message
+ void OnDebugExceptionHandlerLaunched(int32 pid);
// BrowserChildProcessHostDelegate implementation:
virtual bool OnMessageReceived(const IPC::Message& msg);
diff --git a/chrome/browser/nacl_host/nacl_broker_service_win.cc b/chrome/browser/nacl_host/nacl_broker_service_win.cc
index 16bceb5..a338f09 100644
--- a/chrome/browser/nacl_host/nacl_broker_service_win.cc
+++ b/chrome/browser/nacl_host/nacl_broker_service_win.cc
@@ -65,6 +65,25 @@ void NaClBrokerService::OnLoaderDied() {
}
}
+bool NaClBrokerService::LaunchDebugExceptionHandler(
+ NaClProcessHost* nacl_process_host, int32 pid) {
+ pending_debuggers_[pid] = nacl_process_host;
+ NaClBrokerHost* broker_host = GetBrokerHost();
+ if (!broker_host)
+ return false;
+ return broker_host->LaunchDebugExceptionHandler(pid);
+}
+
+void NaClBrokerService::OnDebugExceptionHandlerLaunched(int32 pid) {
+ PendingDebugExceptionHandlersMap::iterator it = pending_debuggers_.find(pid);
+ if (pending_debuggers_.end() == it)
+ NOTREACHED();
+
+ NaClProcessHost* client = it->second;
+ client->OnDebugExceptionHandlerLaunchedByBroker();
+ pending_debuggers_.erase(it);
+}
+
NaClBrokerHost* NaClBrokerService::GetBrokerHost() {
BrowserChildProcessHostIterator iter(content::PROCESS_TYPE_NACL_BROKER);
if (iter.Done())
diff --git a/chrome/browser/nacl_host/nacl_broker_service_win.h b/chrome/browser/nacl_host/nacl_broker_service_win.h
index c69da7b..2b04938 100644
--- a/chrome/browser/nacl_host/nacl_broker_service_win.h
+++ b/chrome/browser/nacl_host/nacl_broker_service_win.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 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.
@@ -34,9 +34,15 @@ class NaClBrokerService {
// Called by NaClProcessHost when a loader process is terminated
void OnLoaderDied();
+ bool LaunchDebugExceptionHandler(NaClProcessHost* client, int32 pid);
+
+ // Called by NaClBrokerHost to notify the service that a debug
+ // exception handler was started.
+ void OnDebugExceptionHandlerLaunched(int32 pid);
+
private:
- typedef std::map<std::wstring, NaClProcessHost*>
- PendingLaunchesMap;
+ typedef std::map<std::wstring, NaClProcessHost*> PendingLaunchesMap;
+ typedef std::map<int, NaClProcessHost*> PendingDebugExceptionHandlersMap;
friend struct DefaultSingletonTraits<NaClBrokerService>;
@@ -47,6 +53,7 @@ class NaClBrokerService {
int loaders_running_;
PendingLaunchesMap pending_launches_;
+ PendingDebugExceptionHandlersMap pending_debuggers_;
DISALLOW_COPY_AND_ASSIGN(NaClBrokerService);
};
diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc
index 1cbab6f..65ce107 100644
--- a/chrome/browser/nacl_host/nacl_process_host.cc
+++ b/chrome/browser/nacl_host/nacl_process_host.cc
@@ -258,9 +258,7 @@ NaClProcessHost::NaClProcessHost(const std::wstring& url)
getenv("NACL_UNTRUSTED_EXCEPTION_HANDLING") != NULL) {
enable_exception_handling_ = true;
#if defined(OS_WIN)
- if (!RunningOnWOW64()) {
- debug_context_ = new DebugContext();
- }
+ debug_context_ = new DebugContext();
#endif
}
}
@@ -505,14 +503,18 @@ bool NaClProcessHost::LaunchSelLdr() {
return true;
}
-void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) {
#if defined(OS_WIN)
+void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) {
process_launched_by_broker_ = true;
-#endif
process_->SetHandle(handle);
OnProcessLaunched();
}
+void NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker() {
+ debug_context_->AllowAndSendStartMessage();
+}
+#endif
+
void NaClProcessHost::OnProcessCrashed(int exit_code) {
std::string message = base::StringPrintf(
"NaCl process exited with status %i (0x%x)", exit_code, exit_code);
@@ -646,38 +648,45 @@ void NaClProcessHost::OnChannelConnected(int32 peer_pid) {
if (debug_context_ == NULL) {
return;
}
- // Start new thread for debug loop
debug_context_->SetChildProcessHost(process_->GetHost());
- // We can't use process_->GetData().handle because it doesn't have necessary
- // access rights.
- base::ProcessHandle process;
- if (!base::OpenProcessHandleWithAccess(
- peer_pid,
- base::kProcessAccessQueryInformation |
- base::kProcessAccessSuspendResume |
- base::kProcessAccessTerminate |
- base::kProcessAccessVMOperation |
- base::kProcessAccessVMRead |
- base::kProcessAccessVMWrite |
- base::kProcessAccessWaitForTermination,
- &process)) {
- LOG(ERROR) << "Failed to open the process";
- debug_context_->AllowAndSendStartMessage();
- return;
- }
- base::Thread* dbg_thread = new base::Thread("Debug thread");
- if (!dbg_thread->Start()) {
- LOG(ERROR) << "Debug thread not started";
- debug_context_->AllowAndSendStartMessage();
- base::CloseProcessHandle(process);
- return;
+ if (RunningOnWOW64()) {
+ if (!NaClBrokerService::GetInstance()->LaunchDebugExceptionHandler(
+ this, peer_pid)) {
+ debug_context_->AllowAndSendStartMessage();
+ }
+ } else {
+ // Start new thread for debug loop
+ // We can't use process_->GetData().handle because it doesn't have necessary
+ // access rights.
+ base::ProcessHandle process;
+ if (!base::OpenProcessHandleWithAccess(
+ peer_pid,
+ base::kProcessAccessQueryInformation |
+ base::kProcessAccessSuspendResume |
+ base::kProcessAccessTerminate |
+ base::kProcessAccessVMOperation |
+ base::kProcessAccessVMRead |
+ base::kProcessAccessVMWrite |
+ base::kProcessAccessWaitForTermination,
+ &process)) {
+ LOG(ERROR) << "Failed to open the process";
+ debug_context_->AllowAndSendStartMessage();
+ return;
+ }
+ base::Thread* dbg_thread = new base::Thread("Debug thread");
+ if (!dbg_thread->Start()) {
+ LOG(ERROR) << "Debug thread not started";
+ debug_context_->AllowAndSendStartMessage();
+ base::CloseProcessHandle(process);
+ return;
+ }
+ debug_context_->SetDebugThread(dbg_thread);
+ // System can not reallocate pid until we close process handle. So using
+ // pid in different thread is fine.
+ dbg_thread->message_loop()->PostTask(FROM_HERE,
+ base::Bind(&NaClProcessHost::DebugContext::AttachDebugger,
+ debug_context_, peer_pid, process));
}
- debug_context_->SetDebugThread(dbg_thread);
- // System can not reallocate pid until we close process handle. So using
- // pid in different thread is fine.
- dbg_thread->message_loop()->PostTask(FROM_HERE,
- base::Bind(&NaClProcessHost::DebugContext::AttachDebugger,
- debug_context_, peer_pid, process));
}
#else
void NaClProcessHost::OnChannelConnected(int32 peer_pid) {
diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h
index d050179..f5e51ec 100644
--- a/chrome/browser/nacl_host/nacl_process_host.h
+++ b/chrome/browser/nacl_host/nacl_process_host.h
@@ -47,7 +47,10 @@ class NaClProcessHost : public content::BrowserChildProcessHostDelegate {
virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
+#if defined(OS_WIN)
void OnProcessLaunchedByBroker(base::ProcessHandle handle);
+ void OnDebugExceptionHandlerLaunchedByBroker();
+#endif
private:
// Internal class that holds the nacl::Handle objecs so that