diff options
-rw-r--r-- | chrome/app/chrome_main.cc | 1 | ||||
-rw-r--r-- | content/gpu/gpu_child_thread.cc | 69 | ||||
-rw-r--r-- | content/gpu/gpu_child_thread.h | 9 | ||||
-rw-r--r-- | content/gpu/gpu_main.cc | 46 |
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); |