summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorkbr@google.com <kbr@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-22 18:13:28 +0000
committerkbr@google.com <kbr@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-22 18:13:28 +0000
commit0b2cec69a613d94f2ee72743ba53f539843e85e3 (patch)
tree8ed8627b2fd91716f11b16a5b8174b611f6b33c3 /content
parent638b1808f8c609dbf58c319837a78f1c316f82cd (diff)
downloadchromium_src-0b2cec69a613d94f2ee72743ba53f539843e85e3.zip
chromium_src-0b2cec69a613d94f2ee72743ba53f539843e85e3.tar.gz
chromium_src-0b2cec69a613d94f2ee72743ba53f539843e85e3.tar.bz2
Initialize the sandbox earlier in GPU process bringup, deferring any
errors until receipt of the first IPC message. Tested by running WebGL content with this patch on Mac and Windows. BUG=84650 TEST=none Review URL: http://codereview.chromium.org/7458009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@93676 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/gpu/gpu_child_thread.cc69
-rw-r--r--content/gpu/gpu_child_thread.h9
-rw-r--r--content/gpu/gpu_main.cc46
3 files changed, 49 insertions, 75 deletions
diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc
index 62336cc..c854fb3 100644
--- a/content/gpu/gpu_child_thread.cc
+++ b/content/gpu/gpu_child_thread.cc
@@ -19,31 +19,11 @@
#include "content/gpu/gpu_watchdog_thread.h"
#include "ipc/ipc_channel_handle.h"
#include "ui/gfx/gl/gl_implementation.h"
-#include "ui/gfx/gl/gl_surface.h"
-
-#if defined(OS_MACOSX)
-#include "content/common/sandbox_init_wrapper.h"
-#include "content/common/sandbox_mac.h"
-#elif defined(OS_WIN)
-#include "sandbox/src/sandbox.h"
-#endif
const int kGpuTimeout = 10000;
namespace {
-bool InitializeGpuSandbox() {
-#if defined(OS_MACOSX)
- CommandLine* parsed_command_line = CommandLine::ForCurrentProcess();
- SandboxInitWrapper sandbox_wrapper;
- return sandbox_wrapper.InitializeSandbox(*parsed_command_line,
- switches::kGpuProcess);
-#else
- // TODO(port): Create GPU sandbox for linux.
- return true;
-#endif
-}
-
bool GpuProcessLogMessageHandler(int severity,
const char* file, int line,
size_t message_start,
@@ -57,18 +37,16 @@ bool GpuProcessLogMessageHandler(int severity,
} // namespace
+GpuChildThread::GpuChildThread(bool dead_on_arrival)
+ : dead_on_arrival_(dead_on_arrival) {
#if defined(OS_WIN)
-GpuChildThread::GpuChildThread(sandbox::TargetServices* target_services)
- : target_services_(target_services),
- collecting_dx_diagnostics_(false) {
-}
-#else
-GpuChildThread::GpuChildThread() {
-}
+ collecting_dx_diagnostics_ = false;
#endif
+}
GpuChildThread::GpuChildThread(const std::string& channel_id)
- : ChildThread(channel_id) {
+ : ChildThread(channel_id),
+ dead_on_arrival_(false) {
#if defined(OS_WIN)
target_services_ = NULL;
collecting_dx_diagnostics_ = false;
@@ -112,20 +90,18 @@ bool GpuChildThread::OnControlMessageReceived(const IPC::Message& msg) {
}
void GpuChildThread::OnInitialize() {
+ if (dead_on_arrival_) {
+ LOG(INFO) << "Exiting GPU process due to errors during initialization";
+ MessageLoop::current()->Quit();
+ return;
+ }
+
// We don't need to pipe log messages if we are running the GPU thread in
// the browser process.
if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) &&
!CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU))
logging::SetLogMessageHandler(GpuProcessLogMessageHandler);
- // Load the GL implementation and locate the bindings before starting the GPU
- // watchdog because this can take a lot of time and the GPU watchdog might
- // terminate the GPU process.
- if (!gfx::GLSurface::InitializeOneOff()) {
- LOG(INFO) << "GLContext::InitializeOneOff failed";
- MessageLoop::current()->Quit();
- return;
- }
gpu_info_collector::CollectGraphicsInfo(&gpu_info_);
content::GetContentClient()->SetGpuInfo(gpu_info_);
@@ -135,27 +111,6 @@ void GpuChildThread::OnInitialize() {
// take a significant amount of time.
gpu_info_.initialization_time = base::Time::Now() - process_start_time_;
-#if defined (OS_MACOSX)
- // Note that kNoSandbox will also disable the GPU sandbox.
- bool no_gpu_sandbox = CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableGpuSandbox);
- if (!no_gpu_sandbox) {
- if (!InitializeGpuSandbox()) {
- LOG(ERROR) << "Failed to initialize the GPU sandbox";
- MessageLoop::current()->Quit();
- return;
- }
- } else {
- LOG(ERROR) << "Running without GPU sandbox";
- }
-#elif defined(OS_WIN)
- // For windows, if the target_services interface is not zero, the process
- // is sandboxed and we must call LowerToken() before rendering untrusted
- // content.
- if (target_services_)
- target_services_->LowerToken();
-#endif
-
// In addition to disabling the watchdog if the command line switch is
// present, disable it in two other cases. OSMesa is expected to run very
// slowly. Also disable the watchdog on valgrind because the code is expected
diff --git a/content/gpu/gpu_child_thread.h b/content/gpu/gpu_child_thread.h
index 6fc8fbd..06643dc 100644
--- a/content/gpu/gpu_child_thread.h
+++ b/content/gpu/gpu_child_thread.h
@@ -38,11 +38,7 @@ class GpuWatchdogThread;
// commands to the GPU.
class GpuChildThread : public ChildThread {
public:
-#if defined(OS_WIN)
- explicit GpuChildThread(sandbox::TargetServices* target_services);
-#else
- GpuChildThread();
-#endif
+ explicit GpuChildThread(bool dead_on_arrival);
// For single-process mode.
explicit GpuChildThread(const std::string& channel_id);
@@ -69,6 +65,9 @@ class GpuChildThread : public ChildThread {
static void SetDxDiagnostics(GpuChildThread* thread, const DxDiagNode& node);
#endif
+ // Set this flag to true if a fatal error occurred before we receive the
+ // OnInitialize message, in which case we just declare ourselves DOA.
+ bool dead_on_arrival_;
base::Time process_start_time_;
scoped_refptr<GpuWatchdogThread> watchdog_thread_;
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
index cea11e6..1b0f58b 100644
--- a/content/gpu/gpu_main.cc
+++ b/content/gpu/gpu_main.cc
@@ -19,9 +19,12 @@
#include "content/common/main_function_params.h"
#include "content/gpu/gpu_child_thread.h"
#include "content/gpu/gpu_process.h"
+#include "ui/gfx/gl/gl_surface.h"
#if defined(OS_MACOSX)
#include "content/common/chrome_application_mac.h"
+#elif defined(OS_WIN)
+#include "sandbox/src/sandbox.h"
#endif
#if defined(USE_X11)
@@ -37,6 +40,35 @@ int GpuMain(const MainFunctionParams& parameters) {
ChildProcess::WaitForDebugger("Gpu");
}
+ // Initialization of the OpenGL bindings may fail, in which case we
+ // will need to tear down this process. However, we can not do so
+ // safely until the IPC channel is set up, because the detection of
+ // early return of a child process is implemented using an IPC
+ // channel error. If the IPC channel is not fully set up between the
+ // browser and GPU process, and the GPU process crashes or exits
+ // early, the browser process will never detect it. For this reason
+ // we defer tearing down the GPU process until receiving the
+ // GpuMsg_Initialize message from the browser.
+ bool dead_on_arrival = false;
+
+#if defined(OS_WIN)
+ sandbox::TargetServices* target_services =
+ parameters.sandbox_info_.TargetServices();
+ // For windows, if the target_services interface is not zero, the process
+ // is sandboxed and we must call LowerToken() before rendering untrusted
+ // content.
+ if (target_services)
+ target_services->LowerToken();
+#endif
+
+ // Load the GL implementation and locate the bindings before starting the GPU
+ // watchdog because this can take a lot of time and the GPU watchdog might
+ // terminate the GPU process.
+ if (!gfx::GLSurface::InitializeOneOff()) {
+ LOG(INFO) << "GLContext::InitializeOneOff failed";
+ dead_on_arrival = true;
+ }
+
#if defined(OS_MACOSX)
chrome_application_mac::RegisterCrApp();
#endif
@@ -59,21 +91,9 @@ int GpuMain(const MainFunctionParams& parameters) {
base::win::ScopedCOMInitializer com_initializer;
- // We can not tolerate early returns from this code, because the
- // detection of early return of a child process is implemented using
- // an IPC channel error. If the IPC channel is not fully set up
- // between the browser and GPU process, and the GPU process crashes
- // or exits early, the browser process will never detect it. For
- // this reason we defer all work related to the GPU until receiving
- // the GpuMsg_Initialize message from the browser.
GpuProcess gpu_process;
- GpuChildThread* child_thread =
-#if defined(OS_WIN)
- new GpuChildThread(parameters.sandbox_info_.TargetServices());
-#else
- new GpuChildThread;
-#endif
+ GpuChildThread* child_thread = new GpuChildThread(dead_on_arrival);
child_thread->Init(start_time);