diff options
author | alemate@chromium.org <alemate@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-02 18:01:50 +0000 |
---|---|---|
committer | alemate@chromium.org <alemate@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-02 18:01:50 +0000 |
commit | cec95636bbd3585dc60b33c5686213ac463496bb (patch) | |
tree | 5bfeae0ee970fe3931730098cdf3b565dbe3e539 /content | |
parent | 818f73686cbfc0902bd63d22134e4a246474ae4a (diff) | |
download | chromium_src-cec95636bbd3585dc60b33c5686213ac463496bb.zip chromium_src-cec95636bbd3585dc60b33c5686213ac463496bb.tar.gz chromium_src-cec95636bbd3585dc60b33c5686213ac463496bb.tar.bz2 |
Store unsaved trace data on exit.
This CL enables chromeos chrome startup trace when chrome in restarted on
user log in: startup trace should be saved to disk on process exit if
"trace-startup-duration" period has not ended yet.
BUG=346913
TEST=manual
Review URL: https://codereview.chromium.org/359473006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@281061 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/browser_main_loop.cc | 32 | ||||
-rw-r--r-- | content/browser/browser_main_loop.h | 16 | ||||
-rw-r--r-- | content/browser/browser_main_runner.cc | 21 | ||||
-rw-r--r-- | content/browser/browser_shutdown_profile_dumper.cc | 25 | ||||
-rw-r--r-- | content/browser/browser_shutdown_profile_dumper.h | 14 |
5 files changed, 77 insertions, 31 deletions
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index c7b1998..6b5cdd4 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc @@ -903,6 +903,10 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() { } } +void BrowserMainLoop::StopStartupTracingTimer() { + startup_trace_timer_.Stop(); +} + void BrowserMainLoop::InitializeMainThread() { TRACE_EVENT0("startup", "BrowserMainLoop::InitializeMainThread"); const char* kThreadName = "CrBrowserMain"; @@ -1107,16 +1111,15 @@ void BrowserMainLoop::MainMessageLoopRun() { #endif } -void BrowserMainLoop::InitStartupTracing(const CommandLine& command_line) { - DCHECK(is_tracing_startup_); - +base::FilePath BrowserMainLoop::GetStartupTraceFileName( + const base::CommandLine& command_line) const { base::FilePath trace_file = command_line.GetSwitchValuePath( switches::kTraceStartupFile); // trace_file = "none" means that startup events will show up for the next // begin/end tracing (via about:tracing or AutomationProxy::BeginTracing/ // EndTracing, for example). if (trace_file == base::FilePath().AppendASCII("none")) - return; + return trace_file; if (trace_file.empty()) { #if defined(OS_ANDROID) @@ -1127,6 +1130,14 @@ void BrowserMainLoop::InitStartupTracing(const CommandLine& command_line) { #endif } + return trace_file; +} + +void BrowserMainLoop::InitStartupTracing(const CommandLine& command_line) { + DCHECK(is_tracing_startup_); + + startup_trace_file_ = GetStartupTraceFileName(parsed_command_line_); + std::string delay_str = command_line.GetSwitchValueASCII( switches::kTraceStartupDuration); int delay_secs = 5; @@ -1136,17 +1147,16 @@ void BrowserMainLoop::InitStartupTracing(const CommandLine& command_line) { delay_secs = 5; } - BrowserThread::PostDelayedTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&BrowserMainLoop::EndStartupTracing, - base::Unretained(this), trace_file), - base::TimeDelta::FromSeconds(delay_secs)); + startup_trace_timer_.Start(FROM_HERE, + base::TimeDelta::FromSeconds(delay_secs), + this, + &BrowserMainLoop::EndStartupTracing); } -void BrowserMainLoop::EndStartupTracing(const base::FilePath& trace_file) { +void BrowserMainLoop::EndStartupTracing() { is_tracing_startup_ = false; TracingController::GetInstance()->DisableRecording( - trace_file, base::Bind(&OnStoppedStartupTracing)); + startup_trace_file_, base::Bind(&OnStoppedStartupTracing)); } } // namespace content diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h index f38ac42..14370fd 100644 --- a/content/browser/browser_main_loop.h +++ b/content/browser/browser_main_loop.h @@ -6,8 +6,10 @@ #define CONTENT_BROWSER_BROWSER_MAIN_LOOP_H_ #include "base/basictypes.h" +#include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/timer/timer.h" #include "content/browser/browser_process_sub_thread.h" #include "content/public/browser/browser_main_runner.h" @@ -104,6 +106,12 @@ class CONTENT_EXPORT BrowserMainLoop { bool is_tracing_startup() const { return is_tracing_startup_; } + const base::FilePath& startup_trace_file() const { + return startup_trace_file_; + } + + void StopStartupTracingTimer(); + #if defined(OS_MACOSX) && !defined(OS_IOS) DeviceMonitorMac* device_monitor_mac() const { return device_monitor_mac_.get(); @@ -130,8 +138,10 @@ class CONTENT_EXPORT BrowserMainLoop { void MainMessageLoopRun(); + base::FilePath GetStartupTraceFileName( + const base::CommandLine& command_line) const; void InitStartupTracing(const base::CommandLine& command_line); - void EndStartupTracing(const base::FilePath& trace_file); + void EndStartupTracing(); // Members initialized on construction --------------------------------------- const MainFunctionParams& parameters_; @@ -190,6 +200,10 @@ class CONTENT_EXPORT BrowserMainLoop { scoped_ptr<base::debug::TraceEventSystemStatsMonitor> system_stats_monitor_; bool is_tracing_startup_; + base::FilePath startup_trace_file_; + + // This timer initiates trace file saving. + base::OneShotTimer<BrowserMainLoop> startup_trace_timer_; DISALLOW_COPY_AND_ASSIGN(BrowserMainLoop); }; diff --git a/content/browser/browser_main_runner.cc b/content/browser/browser_main_runner.cc index c41fc95..8701c07 100644 --- a/content/browser/browser_main_runner.cc +++ b/content/browser/browser_main_runner.cc @@ -130,13 +130,28 @@ class BrowserMainRunnerImpl : public BrowserMainRunner { // If leaks are found, the process will exit here. __lsan_do_leak_check(); #endif + // If startup tracing has not been finished yet, replace it's dumper + // with special version, which would save trace file on exit (i.e. + // startup tracing becomes a version of shutdown tracing). + scoped_ptr<BrowserShutdownProfileDumper> startup_profiler; + if (main_loop_->is_tracing_startup()) { + main_loop_->StopStartupTracingTimer(); + if (main_loop_->startup_trace_file() != + base::FilePath().AppendASCII("none")) { + startup_profiler.reset( + new BrowserShutdownProfileDumper(main_loop_->startup_trace_file())); + } + } + // The shutdown tracing got enabled in AttemptUserExit earlier, but someone // needs to write the result to disc. For that a dumper needs to get created // which will dump the traces to disc when it gets destroyed. const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - scoped_ptr<BrowserShutdownProfileDumper> profiler; - if (command_line.HasSwitch(switches::kTraceShutdown)) - profiler.reset(new BrowserShutdownProfileDumper()); + scoped_ptr<BrowserShutdownProfileDumper> shutdown_profiler; + if (command_line.HasSwitch(switches::kTraceShutdown)) { + shutdown_profiler.reset(new BrowserShutdownProfileDumper( + BrowserShutdownProfileDumper::GetShutdownProfileFileName())); + } { // The trace event has to stay between profiler creation and destruction. diff --git a/content/browser/browser_shutdown_profile_dumper.cc b/content/browser/browser_shutdown_profile_dumper.cc index 3e74e06..a8b9e952 100644 --- a/content/browser/browser_shutdown_profile_dumper.cc +++ b/content/browser/browser_shutdown_profile_dumper.cc @@ -18,17 +18,18 @@ namespace content { -BrowserShutdownProfileDumper::BrowserShutdownProfileDumper() - : blocks_(0), +BrowserShutdownProfileDumper::BrowserShutdownProfileDumper( + const base::FilePath& dump_file_name) + : dump_file_name_(dump_file_name), + blocks_(0), dump_file_(NULL) { } BrowserShutdownProfileDumper::~BrowserShutdownProfileDumper() { - WriteTracesToDisc(GetFileName()); + WriteTracesToDisc(); } -void BrowserShutdownProfileDumper::WriteTracesToDisc( - const base::FilePath& file_name) { +void BrowserShutdownProfileDumper::WriteTracesToDisc() { // Note: I have seen a usage of 0.000xx% when dumping - which fits easily. // Since the tracer stops when the trace buffer is filled, we'd rather save // what we have than nothing since we might see from the amount of events @@ -37,10 +38,10 @@ void BrowserShutdownProfileDumper::WriteTracesToDisc( base::debug::TraceLog::GetInstance()->GetBufferPercentFull() << " full."; DCHECK(!dump_file_); - dump_file_ = base::OpenFile(file_name, "w+"); + dump_file_ = base::OpenFile(dump_file_name_, "w+"); if (!IsFileValid()) { - LOG(ERROR) << "Failed to open performance trace file: " << - file_name.value(); + LOG(ERROR) << "Failed to open performance trace file: " + << dump_file_name_.value(); return; } WriteString("{\"traceEvents\":"); @@ -72,7 +73,8 @@ void BrowserShutdownProfileDumper::EndTraceAndFlush( base::Unretained(flush_complete_event))); } -base::FilePath BrowserShutdownProfileDumper::GetFileName() { +// static +base::FilePath BrowserShutdownProfileDumper::GetShutdownProfileFileName() { const CommandLine& command_line = *CommandLine::ForCurrentProcess(); base::FilePath trace_file = command_line.GetSwitchValuePath(switches::kTraceShutdownFile); @@ -122,8 +124,9 @@ void BrowserShutdownProfileDumper::WriteChars(const char* chars, size_t size) { size_t written = fwrite(chars, 1, size, dump_file_); if (written != size) { - LOG(ERROR) << "Error " << ferror(dump_file_) << - " in fwrite() to trace file"; + LOG(ERROR) << "Error " << ferror(dump_file_) + << " in fwrite() to trace file '" << dump_file_name_.value() + << "'"; CloseFile(); } } diff --git a/content/browser/browser_shutdown_profile_dumper.h b/content/browser/browser_shutdown_profile_dumper.h index f98a32c..cc8666e 100644 --- a/content/browser/browser_shutdown_profile_dumper.h +++ b/content/browser/browser_shutdown_profile_dumper.h @@ -8,6 +8,7 @@ #include <string> #include "base/basictypes.h" +#include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/memory/ref_counted_memory.h" #include "content/common/content_export.h" @@ -29,19 +30,19 @@ namespace content { // |SequencedWorkerPool| will get killed in the shutdown process. class BrowserShutdownProfileDumper { public: - BrowserShutdownProfileDumper(); + explicit BrowserShutdownProfileDumper(const base::FilePath& dump_file_name); ~BrowserShutdownProfileDumper(); + // Returns the file name where we should save the shutdown trace dump to. + static base::FilePath GetShutdownProfileFileName(); + private: // Writes all traces which happened to disk. - void WriteTracesToDisc(const base::FilePath& file_name); + void WriteTracesToDisc(); void EndTraceAndFlush(base::WaitableEvent* flush_complete_event); - // Returns the file name where we should save the trace dump to. - base::FilePath GetFileName(); - // The callback for the |TraceLog::Flush| function. It saves all traces to // disc. void WriteTraceDataCollected( @@ -61,6 +62,9 @@ class BrowserShutdownProfileDumper { // Closes the dump file. void CloseFile(); + // The name of the dump file. + const base::FilePath dump_file_name_; + // The number of blocks we have already written. int blocks_; // For dumping the content to disc. |