Commit 1b6beceb authored by Dale Curtis's avatar Dale Curtis Committed by Commit Bot

Ensure GPU logs are not lost during some stages of startup.

Prior to this change there exists a window between when GpuMain()
hands off log collection and when GpuServiceImpl::InitializeWithHost()
starts forwarding to the GpuProcessHost. We have sometimes lost key
debugging logs in these cases.

Now GpuServiceImpl handles collection of GpuMain() logs all the way up
until GpuServiceImpl::InitializeWithHost() takes over, so no logs are
lost during startup.

Fixed: 1065082
Change-Id: I1d0376ca917218cb6cb6c7298ad59021ba6832ad
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2123329
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: default avatardanakj <danakj@chromium.org>
Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#754614}
parent 9839791f
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/lazy_instance.h" #include "base/lazy_instance.h"
#include "base/no_destructor.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/task/thread_pool.h" #include "base/task/thread_pool.h"
#include "base/task_runner_util.h" #include "base/task_runner_util.h"
...@@ -101,9 +102,45 @@ namespace viz { ...@@ -101,9 +102,45 @@ namespace viz {
namespace { namespace {
static base::LazyInstance<base::RepeatingCallback< static base::LazyInstance<base::RepeatingCallback<void(
void(int severity, size_t message_start, const std::string& message)>>:: int severity,
Leaky g_log_callback = LAZY_INSTANCE_INITIALIZER; const std::string& header,
const std::string& message)>>::Leaky g_log_callback =
LAZY_INSTANCE_INITIALIZER;
bool GpuLogMessageHandler(int severity,
const char* file,
int line,
size_t message_start,
const std::string& message) {
g_log_callback.Get().Run(severity, message.substr(0, message_start),
message.substr(message_start));
return false;
}
struct LogMessage {
LogMessage(int severity,
const std::string& header,
const std::string& message)
: severity(severity),
header(std::move(header)),
message(std::move(message)) {}
const int severity;
const std::string header;
const std::string message;
};
std::vector<LogMessage>* GetDeferredLogMessages() {
static base::NoDestructor<std::vector<LogMessage>> deferred_messages;
return deferred_messages.get();
}
void PreInitializeGlobalLogCallback(int severity,
const std::string& header,
const std::string& message) {
GetDeferredLogMessages()->emplace_back(severity, std::move(header),
std::move(message));
}
bool IsAcceleratedJpegDecodeSupported() { bool IsAcceleratedJpegDecodeSupported() {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
...@@ -114,15 +151,6 @@ bool IsAcceleratedJpegDecodeSupported() { ...@@ -114,15 +151,6 @@ bool IsAcceleratedJpegDecodeSupported() {
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
} }
bool GpuLogMessageHandler(int severity,
const char* file,
int line,
size_t message_start,
const std::string& message) {
g_log_callback.Get().Run(severity, message_start, message);
return false;
}
// Returns a callback which does a PostTask to run |callback| on the |runner| // Returns a callback which does a PostTask to run |callback| on the |runner|
// task runner. // task runner.
template <typename... Params> template <typename... Params>
...@@ -325,6 +353,9 @@ void GpuServiceImpl::InitializeWithHost( ...@@ -325,6 +353,9 @@ void GpuServiceImpl::InitializeWithHost(
g_log_callback.Get() = base::BindRepeating( g_log_callback.Get() = base::BindRepeating(
&GpuServiceImpl::RecordLogMessage, base::Unretained(this)); &GpuServiceImpl::RecordLogMessage, base::Unretained(this));
logging::SetLogMessageHandler(GpuLogMessageHandler); logging::SetLogMessageHandler(GpuLogMessageHandler);
// Flush any log messages that may have occurred before we took over.
FlushPreInitializeLogMessages(gpu_host_.get());
} }
if (!sync_point_manager) { if (!sync_point_manager) {
...@@ -404,13 +435,25 @@ gpu::ImageFactory* GpuServiceImpl::gpu_image_factory() { ...@@ -404,13 +435,25 @@ gpu::ImageFactory* GpuServiceImpl::gpu_image_factory() {
: nullptr; : nullptr;
} }
// static
void GpuServiceImpl::InstallPreInitializeLogHandler() {
g_log_callback.Get() = base::BindRepeating(&PreInitializeGlobalLogCallback);
logging::SetLogMessageHandler(GpuLogMessageHandler);
}
// static
void GpuServiceImpl::FlushPreInitializeLogMessages(mojom::GpuHost* gpu_host) {
std::vector<LogMessage>& log_messages = *GetDeferredLogMessages();
for (const auto& log : log_messages)
gpu_host->RecordLogMessage(log.severity, log.header, log.message);
log_messages.clear();
}
void GpuServiceImpl::RecordLogMessage(int severity, void GpuServiceImpl::RecordLogMessage(int severity,
size_t message_start, const std::string& header,
const std::string& str) { const std::string& message) {
// This can be run from any thread. // This can be run from any thread.
std::string header = str.substr(0, message_start); gpu_host_->RecordLogMessage(severity, std::move(header), std::move(message));
std::string message = str.substr(message_start);
gpu_host_->RecordLogMessage(severity, header, message);
} }
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
......
...@@ -217,6 +217,16 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate, ...@@ -217,6 +217,16 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate,
gpu::SurfaceHandle child_window) override; gpu::SurfaceHandle child_window) override;
#endif #endif
// Installs a base::LogMessageHandlerFunction which ensures messages are sent
// to the mojom::GpuHost once InitializeWithHost() completes.
//
// In the event of aborted initialization, FlushPreInitializeLogMessages() may
// be called to flush the accumulated logs to the remote host.
//
// Note: ~GpuServiceImpl() will clear installed log handlers.
static void InstallPreInitializeLogHandler();
static void FlushPreInitializeLogMessages(mojom::GpuHost* gpu_host);
bool is_initialized() const { return !!gpu_host_; } bool is_initialized() const { return !!gpu_host_; }
media::MediaGpuChannelManager* media_gpu_channel_manager() { media::MediaGpuChannelManager* media_gpu_channel_manager() {
...@@ -296,7 +306,7 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate, ...@@ -296,7 +306,7 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate,
private: private:
void RecordLogMessage(int severity, void RecordLogMessage(int severity,
size_t message_start, const std::string& header,
const std::string& message); const std::string& message);
void UpdateGpuInfoPlatform(base::OnceClosure on_gpu_info_updated); void UpdateGpuInfoPlatform(base::OnceClosure on_gpu_info_updated);
......
...@@ -127,10 +127,6 @@ VizMainImpl::~VizMainImpl() { ...@@ -127,10 +127,6 @@ VizMainImpl::~VizMainImpl() {
dependencies_.ukm_recorder.get()); dependencies_.ukm_recorder.get());
} }
void VizMainImpl::SetLogMessagesForHost(LogMessages log_messages) {
log_messages_ = std::move(log_messages);
}
void VizMainImpl::BindAssociated( void VizMainImpl::BindAssociated(
mojo::PendingAssociatedReceiver<mojom::VizMain> pending_receiver) { mojo::PendingAssociatedReceiver<mojom::VizMain> pending_receiver) {
receiver_.Bind(std::move(pending_receiver)); receiver_.Bind(std::move(pending_receiver));
...@@ -152,11 +148,9 @@ void VizMainImpl::CreateGpuService( ...@@ -152,11 +148,9 @@ void VizMainImpl::CreateGpuService(
if (gl::GetGLImplementation() != gl::kGLImplementationDisabled) if (gl::GetGLImplementation() != gl::kGLImplementationDisabled)
gpu_service_->UpdateGPUInfo(); gpu_service_->UpdateGPUInfo();
for (const LogMessage& log : log_messages_)
gpu_host->RecordLogMessage(log.severity, log.header, log.message);
log_messages_.clear();
if (!gpu_init_->init_successful()) { if (!gpu_init_->init_successful()) {
LOG(ERROR) << "Exiting GPU process due to errors during initialization"; LOG(ERROR) << "Exiting GPU process due to errors during initialization";
GpuServiceImpl::FlushPreInitializeLogMessages(gpu_host.get());
gpu_service_.reset(); gpu_service_.reset();
gpu_host->DidFailInitialize(); gpu_host->DidFailInitialize();
if (delegate_) if (delegate_)
......
...@@ -45,13 +45,6 @@ class GpuServiceImpl; ...@@ -45,13 +45,6 @@ class GpuServiceImpl;
class VizMainImpl : public mojom::VizMain, class VizMainImpl : public mojom::VizMain,
public gpu::GpuInProcessThreadServiceDelegate { public gpu::GpuInProcessThreadServiceDelegate {
public: public:
struct LogMessage {
int severity;
std::string header;
std::string message;
};
using LogMessages = std::vector<LogMessage>;
class Delegate { class Delegate {
public: public:
virtual ~Delegate() = default; virtual ~Delegate() = default;
...@@ -105,8 +98,6 @@ class VizMainImpl : public mojom::VizMain, ...@@ -105,8 +98,6 @@ class VizMainImpl : public mojom::VizMain,
// Destruction must happen on the GPU thread. // Destruction must happen on the GPU thread.
~VizMainImpl() override; ~VizMainImpl() override;
void SetLogMessagesForHost(LogMessages messages);
void BindAssociated( void BindAssociated(
mojo::PendingAssociatedReceiver<mojom::VizMain> pending_receiver); mojo::PendingAssociatedReceiver<mojom::VizMain> pending_receiver);
...@@ -156,8 +147,6 @@ class VizMainImpl : public mojom::VizMain, ...@@ -156,8 +147,6 @@ class VizMainImpl : public mojom::VizMain,
// destroyed after they are. // destroyed after they are.
std::unique_ptr<base::Thread> io_thread_; std::unique_ptr<base::Thread> io_thread_;
LogMessages log_messages_;
std::unique_ptr<gpu::GpuInit> gpu_init_; std::unique_ptr<gpu::GpuInit> gpu_init_;
std::unique_ptr<GpuServiceImpl> gpu_service_; std::unique_ptr<GpuServiceImpl> gpu_service_;
......
...@@ -98,13 +98,10 @@ viz::VizMainImpl::ExternalDependencies CreateVizMainDependencies() { ...@@ -98,13 +98,10 @@ viz::VizMainImpl::ExternalDependencies CreateVizMainDependencies() {
} // namespace } // namespace
GpuChildThread::GpuChildThread(base::RepeatingClosure quit_closure, GpuChildThread::GpuChildThread(base::RepeatingClosure quit_closure,
std::unique_ptr<gpu::GpuInit> gpu_init, std::unique_ptr<gpu::GpuInit> gpu_init)
viz::VizMainImpl::LogMessages log_messages)
: GpuChildThread(std::move(quit_closure), : GpuChildThread(std::move(quit_closure),
GetOptions(), GetOptions(),
std::move(gpu_init)) { std::move(gpu_init)) {}
viz_main_.SetLogMessagesForHost(std::move(log_messages));
}
GpuChildThread::GpuChildThread(const InProcessChildThreadParams& params, GpuChildThread::GpuChildThread(const InProcessChildThreadParams& params,
std::unique_ptr<gpu::GpuInit> gpu_init) std::unique_ptr<gpu::GpuInit> gpu_init)
......
...@@ -48,8 +48,7 @@ class GpuChildThread : public ChildThreadImpl, ...@@ -48,8 +48,7 @@ class GpuChildThread : public ChildThreadImpl,
public viz::VizMainImpl::Delegate { public viz::VizMainImpl::Delegate {
public: public:
GpuChildThread(base::RepeatingClosure quit_closure, GpuChildThread(base::RepeatingClosure quit_closure,
std::unique_ptr<gpu::GpuInit> gpu_init, std::unique_ptr<gpu::GpuInit> gpu_init);
viz::VizMainImpl::LogMessages deferred_messages);
GpuChildThread(const InProcessChildThreadParams& params, GpuChildThread(const InProcessChildThreadParams& params,
std::unique_ptr<gpu::GpuInit> gpu_init); std::unique_ptr<gpu::GpuInit> gpu_init);
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/lazy_instance.h"
#include "base/message_loop/message_pump_type.h" #include "base/message_loop/message_pump_type.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/rand_util.h" #include "base/rand_util.h"
...@@ -118,21 +117,6 @@ bool StartSandboxLinux(gpu::GpuWatchdogThread*, ...@@ -118,21 +117,6 @@ bool StartSandboxLinux(gpu::GpuWatchdogThread*,
bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo*); bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo*);
#endif #endif
base::LazyInstance<viz::VizMainImpl::LogMessages>::DestructorAtExit
deferred_messages = LAZY_INSTANCE_INITIALIZER;
bool GpuProcessLogMessageHandler(int severity,
const char* file, int line,
size_t message_start,
const std::string& str) {
viz::VizMainImpl::LogMessage log;
log.severity = severity;
log.header = str.substr(0, message_start);
log.message = str.substr(message_start);
deferred_messages.Get().push_back(std::move(log));
return false;
}
class ContentSandboxHelper : public gpu::GpuSandboxHelper { class ContentSandboxHelper : public gpu::GpuSandboxHelper {
public: public:
ContentSandboxHelper() {} ContentSandboxHelper() {}
...@@ -260,7 +244,9 @@ int GpuMain(const MainFunctionParams& parameters) { ...@@ -260,7 +244,9 @@ int GpuMain(const MainFunctionParams& parameters) {
::SetPriorityClass(::GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); ::SetPriorityClass(::GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);
#endif #endif
logging::SetLogMessageHandler(GpuProcessLogMessageHandler); // Installs a base::LogMessageHandlerFunction which ensures messages are sent
// to the GpuProcessHost once the GpuServiceImpl has started.
viz::GpuServiceImpl::InstallPreInitializeLogHandler();
// We are experiencing what appear to be memory-stomp issues in the GPU // We are experiencing what appear to be memory-stomp issues in the GPU
// process. These issues seem to be impacting the task executor and listeners // process. These issues seem to be impacting the task executor and listeners
...@@ -356,7 +342,6 @@ int GpuMain(const MainFunctionParams& parameters) { ...@@ -356,7 +342,6 @@ int GpuMain(const MainFunctionParams& parameters) {
const_cast<base::CommandLine*>(&command_line), gpu_preferences); const_cast<base::CommandLine*>(&command_line), gpu_preferences);
const bool dead_on_arrival = !init_success; const bool dead_on_arrival = !init_success;
logging::SetLogMessageHandler(nullptr);
GetContentClient()->SetGpuInfo(gpu_init->gpu_info()); GetContentClient()->SetGpuInfo(gpu_init->gpu_info());
const base::ThreadPriority io_thread_priority = const base::ThreadPriority io_thread_priority =
...@@ -390,10 +375,7 @@ int GpuMain(const MainFunctionParams& parameters) { ...@@ -390,10 +375,7 @@ int GpuMain(const MainFunctionParams& parameters) {
base::RunLoop run_loop; base::RunLoop run_loop;
GpuChildThread* child_thread = GpuChildThread* child_thread =
new GpuChildThread(run_loop.QuitClosure(), std::move(gpu_init), new GpuChildThread(run_loop.QuitClosure(), std::move(gpu_init));
std::move(deferred_messages.Get()));
deferred_messages.Get().clear();
child_thread->Init(start_time); child_thread->Init(start_time);
gpu_process.set_main_thread(child_thread); gpu_process.set_main_thread(child_thread);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment