Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Unified Diff: content/browser/browser_main_runner.cc

Issue 23691025: Adding shutdown tracing capabilities (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Started the profiling in AttemptUserExit instead of BrowserMainRunner::Shutdown. Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/browser_main_runner.cc
diff --git a/content/browser/browser_main_runner.cc b/content/browser/browser_main_runner.cc
index f97318a690657892c4676b1b1d454f9dd75f8a1b..7f3807efea9367376c74cb8d9b64bba2c3800d22 100644
--- a/content/browser/browser_main_runner.cc
+++ b/content/browser/browser_main_runner.cc
@@ -8,6 +8,9 @@
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/debug/trace_event.h"
+#include "base/debug/trace_event_impl.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/metrics/statistics_recorder.h"
@@ -25,6 +28,118 @@
bool g_exited_main_message_loop = false;
+namespace {
+
+// This class is intended to dump the tracing results of the shutdown process
+// to a file before the browser process exits.
+// It will save the file either into the command line passed
+// "--trace-shutdown-file=<name>" parameter - or - to "chrometrace.log".
+// Use the class with a scoped_ptr to automatically write the dump when the
+// object gets destroyed.
+// Note that we cannot use the asynchronous file writer since the
+// |SequencedWorkerPool| will get killed in the shutdown process.
+class BrowserShutdownProfileDumper {
+ public:
+ BrowserShutdownProfileDumper() : blocks_(0), dump_file_(0) {
+ }
+
+ virtual ~BrowserShutdownProfileDumper() {
+ WriteTracesToDisc(GetFileName());
+ }
+
+ private:
+ // Writes all traces which happened to disc.
+ void WriteTracesToDisc(base::FilePath file_name) {
DaveMoore 2013/08/30 22:51:15 What happens if the trace buffer fills up before t
Mr4D (OOO till 08-26) 2013/08/31 02:03:44 As I understood it it will stop tracing when the b
+ LOG(ERROR) << "Flushing shutdown traces to disc. The buffer is %" <<
+ base::debug::TraceLog::GetInstance()->GetBufferPercentFull() <<
+ " full.";
+ DCHECK(!dump_file_);
+ dump_file_ = file_util::OpenFile(file_name, "w+");
+ if (!IsFileValid()) {
+ LOG(ERROR) << "Failed to open performance trace file: " <<
+ file_name.value();
+ return;
+ }
+ WriteString("{\"traceEvents\":");
+ WriteString("[");
+
+ base::debug::TraceLog::GetInstance()->Flush(
+ base::Bind(&BrowserShutdownProfileDumper::WriteTraceDataCollected,
+ base::Unretained(this)));
+
+ WriteString("]");
+ WriteString("}");
+ CloseFile();
+ }
+
+ // Returns the file name where we should save the trace dump to.
+ base::FilePath GetFileName() {
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ base::FilePath trace_file =
+ command_line.GetSwitchValuePath(switches::kTraceShutdownFile);
+
+ if (!trace_file.empty())
+ return trace_file;
+
+ // Default to saving the startup trace into the current dir.
+ return base::FilePath().AppendASCII("chrometrace.log");
+ }
+
+ // The callback for the |TraceLog::Flush| function. It saves all traces to
+ // disc.
+ void WriteTraceDataCollected(
+ const scoped_refptr<base::RefCountedString>& events_str) {
+ if (!IsFileValid())
+ return;
+ if (blocks_) {
+ // Blocks are not comma separated. Beginning with the second block we
+ // start therefore to add one in front of the previous block.
+ WriteString(",");
+ }
+ blocks_++;
+ WriteString(events_str->data());
+ }
+
+ // Returns true if the dump file is valid.
+ bool IsFileValid() {
+ return dump_file_ && (0 == ferror(dump_file_));
+ }
+
+ // Writes a string to the dump file.
+ void WriteString(const std::string& string) {
+ WriteChars(string.data(), string.size());
+
+ }
+
+ // Write a buffer to the dump file.
+ void WriteChars(const char* chars, size_t size) {
+ if (!IsFileValid())
+ return;
+
+ size_t written = fwrite(chars, 1, size, dump_file_);
+ if (written != size) {
+ LOG(ERROR) << "Error " << ferror(dump_file_) <<
+ " in fwrite() to trace file";
+ CloseFile();
+ }
+ }
+
+ // Closes the dump file.
+ void CloseFile() {
+ if (!IsFileValid())
+ return;
+ fclose(dump_file_);
+ dump_file_ = 0;
+ }
+
+ // The number of blocks we have already written.
+ int blocks_;
+ // For dumping the content to disc.
+ FILE* dump_file_;
+};
+
+}
+
namespace content {
class BrowserMainRunnerImpl : public BrowserMainRunner {
@@ -122,22 +237,34 @@ class BrowserMainRunnerImpl : public BrowserMainRunner {
}
virtual void Shutdown() OVERRIDE {
- DCHECK(initialization_started_);
- DCHECK(!is_shutdown_);
- g_exited_main_message_loop = true;
+ // 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());
- main_loop_->ShutdownThreadsAndCleanUp();
+ {
+ // The trace event has to stay between profiler creation and destruction.
+ TRACE_EVENT0("shutdown", "BrowserMainRunner");
+ DCHECK(initialization_started_);
+ DCHECK(!is_shutdown_);
+ g_exited_main_message_loop = true;
- ui::ShutdownInputMethod();
-#if defined(OS_WIN)
- ole_initializer_.reset(NULL);
-#endif
+ main_loop_->ShutdownThreadsAndCleanUp();
- main_loop_.reset(NULL);
+ ui::ShutdownInputMethod();
+ #if defined(OS_WIN)
+ ole_initializer_.reset(NULL);
+ #endif
- notification_service_.reset(NULL);
+ main_loop_.reset(NULL);
- is_shutdown_ = true;
+ notification_service_.reset(NULL);
+
+ is_shutdown_ = true;
+ }
}
protected:

Powered by Google App Engine
This is Rietveld 408576698