summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/chrome_main.cc1
-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
4 files changed, 49 insertions, 76 deletions
diff --git a/chrome/app/chrome_main.cc b/chrome/app/chrome_main.cc
index b85b6d6..00aad89 100644
--- a/chrome/app/chrome_main.cc
+++ b/chrome/app/chrome_main.cc
@@ -848,7 +848,6 @@ int ChromeMain(int argc, char** argv) {
if (process_type == switches::kRendererProcess ||
process_type == switches::kExtensionProcess ||
process_type == switches::kNaClLoaderProcess ||
- process_type == switches::kGpuProcess ||
process_type == switches::kPpapiPluginProcess ||
process_type == switches::kRelauncherProcess) {
initialize_sandbox = false;
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);