Skip to content

Commit

Permalink
Wire gpu process startup error messages to about:gpu
Browse files Browse the repository at this point in the history
This helps us to better understand why the GPU process fails to launch.

BUG=249406
TEST=about:gpu get GPU process startup errors if there are any
R=apatrick@chromium.org

Review URL: https://codereview.chromium.org/17019002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@206420 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
zmo@chromium.org committed Jun 14, 2013
1 parent 0544503 commit ec4bda6
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 9 deletions.
12 changes: 7 additions & 5 deletions content/gpu/gpu_child_thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@

#include "content/gpu/gpu_child_thread.h"

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/threading/worker_pool.h"
#include "build/build_config.h"
#include "content/child/child_process.h"
Expand Down Expand Up @@ -49,9 +45,11 @@ bool GpuProcessLogMessageHandler(int severity,

GpuChildThread::GpuChildThread(GpuWatchdogThread* watchdog_thread,
bool dead_on_arrival,
const gpu::GPUInfo& gpu_info)
const gpu::GPUInfo& gpu_info,
const DeferredMessages& deferred_messages)
: dead_on_arrival_(dead_on_arrival),
gpu_info_(gpu_info),
deferred_messages_(deferred_messages),
in_browser_process_(false) {
watchdog_thread_ = watchdog_thread;
#if defined(OS_WIN)
Expand Down Expand Up @@ -119,6 +117,10 @@ bool GpuChildThread::OnControlMessageReceived(const IPC::Message& msg) {

void GpuChildThread::OnInitialize() {
Send(new GpuHostMsg_Initialized(!dead_on_arrival_, gpu_info_));
while (!deferred_messages_.empty()) {
Send(deferred_messages_.front());
deferred_messages_.pop();
}

if (dead_on_arrival_) {
VLOG(1) << "Exiting GPU process due to errors during initialization";
Expand Down
9 changes: 8 additions & 1 deletion content/gpu/gpu_child_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef CONTENT_GPU_GPU_CHILD_THREAD_H_
#define CONTENT_GPU_GPU_CHILD_THREAD_H_

#include <queue>
#include <string>

#include "base/basictypes.h"
Expand Down Expand Up @@ -34,9 +35,12 @@ class GpuWatchdogThread;
// commands to the GPU.
class GpuChildThread : public ChildThread {
public:
typedef std::queue<IPC::Message*> DeferredMessages;

explicit GpuChildThread(GpuWatchdogThread* gpu_watchdog_thread,
bool dead_on_arrival,
const gpu::GPUInfo& gpu_info);
const gpu::GPUInfo& gpu_info,
const DeferredMessages& deferred_messages);

// For single-process mode.
explicit GpuChildThread(const std::string& channel_id);
Expand Down Expand Up @@ -84,6 +88,9 @@ class GpuChildThread : public ChildThread {
// Information about the GPU, such as device and vendor ID.
gpu::GPUInfo gpu_info_;

// Error messages collected in gpu_main() before the thread is created.
DeferredMessages deferred_messages_;

// Whether the GPU thread is running in the browser process.
bool in_browser_process_;

Expand Down
38 changes: 35 additions & 3 deletions content/gpu/gpu_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#endif

#include "base/debug/trace_event.h"
#include "base/lazy_instance.h"
#include "base/message_loop.h"
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
Expand All @@ -17,6 +18,7 @@
#include "build/build_config.h"
#include "content/child/child_process.h"
#include "content/common/gpu/gpu_config.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/common/sandbox_linux.h"
#include "content/gpu/gpu_child_thread.h"
#include "content/gpu/gpu_process.h"
Expand Down Expand Up @@ -53,15 +55,32 @@
const int kGpuTimeout = 10000;

namespace content {

namespace {

bool WarmUpSandbox(const CommandLine& command_line);
#if defined(OS_LINUX)
bool StartSandboxLinux(const gpu::GPUInfo&, GpuWatchdogThread*, bool);
#elif defined(OS_WIN)
bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo*);
#endif

base::LazyInstance<GpuChildThread::DeferredMessages> deferred_messages =
LAZY_INSTANCE_INITIALIZER;

bool GpuProcessLogMessageHandler(int severity,
const char* file, int line,
size_t message_start,
const std::string& str) {
std::string header = str.substr(0, message_start);
std::string message = str.substr(message_start);
deferred_messages.Get().push(new GpuHostMsg_OnLogMessage(
severity, header, message));
return false;
}

} // namespace anonymous

// Main function for starting the Gpu process.
int GpuMain(const MainFunctionParams& parameters) {
TRACE_EVENT0("gpu", "GpuMain");
Expand All @@ -73,7 +92,10 @@ int GpuMain(const MainFunctionParams& parameters) {

base::Time start_time = base::Time::Now();

if (!command_line.HasSwitch(switches::kSingleProcess)) {
bool in_browser_process = command_line.HasSwitch(switches::kSingleProcess) ||
command_line.HasSwitch(switches::kInProcessGPU);

if (!in_browser_process) {
#if defined(OS_WIN)
// Prevent Windows from displaying a modal dialog on failures like not being
// able to load a DLL.
Expand All @@ -84,6 +106,8 @@ int GpuMain(const MainFunctionParams& parameters) {
#elif defined(USE_X11)
ui::SetDefaultX11ErrorHandlers();
#endif

logging::SetLogMessageHandler(GpuProcessLogMessageHandler);
}

if (command_line.HasSwitch(switches::kSupportsDualGpus) &&
Expand Down Expand Up @@ -198,7 +222,7 @@ int GpuMain(const MainFunctionParams& parameters) {
// crash.
// By skipping the following code on Mac, we don't really lose anything,
// because the basic GPU information is passed down from browser process
// and we already registered them through SetGpuInfo() above.
// and we already registered them through SetGpuInfo() above.
#if !defined(OS_MACOSX)
if (!gpu::CollectContextGraphicsInfo(&gpu_info))
VLOG(1) << "gpu::CollectGraphicsInfo failed";
Expand Down Expand Up @@ -250,12 +274,20 @@ int GpuMain(const MainFunctionParams& parameters) {
#elif defined(OS_WIN)
gpu_info.sandboxed = StartSandboxWindows(parameters.sandbox_info);
#endif
} else {
dead_on_arrival = true;
}

logging::SetLogMessageHandler(NULL);

GpuProcess gpu_process;

GpuChildThread* child_thread = new GpuChildThread(watchdog_thread.get(),
dead_on_arrival, gpu_info);
dead_on_arrival,
gpu_info,
deferred_messages.Get());
while (!deferred_messages.Get().empty())
deferred_messages.Get().pop();

child_thread->Init(start_time);

Expand Down

0 comments on commit ec4bda6

Please sign in to comment.