summaryrefslogtreecommitdiffstats
path: root/components/tracing
diff options
context:
space:
mode:
authorzhenw <zhenw@chromium.org>2015-08-31 10:28:17 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-31 17:28:51 +0000
commitc074d28f557ee0996efb3aa584b8932e1beb837e (patch)
tree466ac51b35adc4c625a505de47c3107146c247f8 /components/tracing
parent3066461da9c580021ec109446fcf4938abf90610 (diff)
downloadchromium_src-c074d28f557ee0996efb3aa584b8932e1beb837e.zip
chromium_src-c074d28f557ee0996efb3aa584b8932e1beb837e.tar.gz
chromium_src-c074d28f557ee0996efb3aa584b8932e1beb837e.tar.bz2
Reland again [Startup Tracing] Add --trace-config-file flag
Original CL: https://codereview.chromium.org/1315463002/ 1st reland: https://codereview.chromium.org/1317333002/ -------- This CL adds --trace-config-file flag. Please see trace_config_file.h for details. Design doc: https://docs.google.com/document/d/1PgdXUOJF3WtEmYWUyGRbC2Fz2ICCZKO9jPvpLPRSHH8/edit?usp=sharing BUG=317481, 482098 TBR=dsinclair@chromium.org,blundell@chromium.org,sievers@chromium.org,sky@chromium.org,msw@chromium.org Review URL: https://codereview.chromium.org/1309243004 Cr-Commit-Position: refs/heads/master@{#346407}
Diffstat (limited to 'components/tracing')
-rw-r--r--components/tracing/BUILD.gn18
-rw-r--r--components/tracing/startup_tracing.cc66
-rw-r--r--components/tracing/startup_tracing.h20
-rw-r--r--components/tracing/trace_config_file.cc140
-rw-r--r--components/tracing/trace_config_file.h94
-rw-r--r--components/tracing/trace_config_file_unittest.cc220
-rw-r--r--components/tracing/tracing_switches.cc4
-rw-r--r--components/tracing/tracing_switches.h1
8 files changed, 475 insertions, 88 deletions
diff --git a/components/tracing/BUILD.gn b/components/tracing/BUILD.gn
index 059f4f1..bd5b271 100644
--- a/components/tracing/BUILD.gn
+++ b/components/tracing/BUILD.gn
@@ -23,8 +23,8 @@ component("tracing") {
component("startup_tracing") {
sources = [
- "startup_tracing.cc",
- "startup_tracing.h",
+ "trace_config_file.cc",
+ "trace_config_file.h",
"tracing_export.h",
"tracing_switches.cc",
"tracing_switches.h",
@@ -36,3 +36,17 @@ component("startup_tracing") {
"//base",
]
}
+
+source_set("unit_tests") {
+ testonly = true
+
+ sources = [
+ "trace_config_file_unittest.cc",
+ ]
+
+ deps = [
+ ":startup_tracing",
+ "//base/test:test_support",
+ "//testing/gtest",
+ ]
+}
diff --git a/components/tracing/startup_tracing.cc b/components/tracing/startup_tracing.cc
deleted file mode 100644
index 321b950..0000000
--- a/components/tracing/startup_tracing.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/tracing/startup_tracing.h"
-
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/path_service.h"
-#include "base/trace_event/trace_event.h"
-
-namespace tracing {
-
-namespace {
-
-// Maximum trace config file size that will be loaded, in bytes.
-const size_t kTraceConfigFileSizeLimit = 64 * 1024;
-
-// Trace config file path:
-// - Android: /data/local/.config/chrome-trace-config.json
-// - POSIX other than Android: $HOME/.config/chrome-trace-config.json
-// - Win: %USERPROFILE%/.config/chrome-trace-config.json
-#if defined(OS_ANDROID)
-const base::FilePath::CharType kAndroidTraceConfigDir[] =
- FILE_PATH_LITERAL("/data/local");
-#endif
-
-const base::FilePath::CharType kChromeConfigDir[] =
- FILE_PATH_LITERAL(".config");
-const base::FilePath::CharType kTraceConfigFileName[] =
- FILE_PATH_LITERAL("chrome-trace-config.json");
-
-base::FilePath GetTraceConfigFilePath() {
-#if defined(OS_ANDROID)
- base::FilePath path(kAndroidTraceConfigDir);
-#elif defined(OS_POSIX) || defined(OS_WIN)
- base::FilePath path;
- PathService::Get(base::DIR_HOME, &path);
-#else
- base::FilePath path;
-#endif
- path = path.Append(kChromeConfigDir);
- path = path.Append(kTraceConfigFileName);
- return path;
-}
-
-} // namespace
-
-void EnableStartupTracingIfConfigFileExists() {
- base::FilePath trace_config_file_path = GetTraceConfigFilePath();
- if (!base::PathExists(trace_config_file_path))
- return;
-
- std::string trace_config_str;
- if (!base::ReadFileToString(trace_config_file_path,
- &trace_config_str,
- kTraceConfigFileSizeLimit)) {
- return;
- }
-
- base::trace_event::TraceConfig trace_config(trace_config_str);
- base::trace_event::TraceLog::GetInstance()->SetEnabled(
- trace_config, base::trace_event::TraceLog::RECORDING_MODE);
-}
-
-} // namespace tracing
diff --git a/components/tracing/startup_tracing.h b/components/tracing/startup_tracing.h
deleted file mode 100644
index 5d1c74d..0000000
--- a/components/tracing/startup_tracing.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_TRACING_STARTUP_TRACING_H_
-#define COMPONENTS_TRACING_STARTUP_TRACING_H_
-
-#include "components/tracing/tracing_export.h"
-
-namespace tracing {
-
-// Enable startup tracing according to the trace config file. If the trace
-// config file does not exist, it will do nothing. This is designed to be used
-// by Telemetry. Telemetry will stop tracing via DevTools later. To avoid
-// conflict, this should not be used when --trace-startup is enabled.
-void TRACING_EXPORT EnableStartupTracingIfConfigFileExists();
-
-} // namespace tracing
-
-#endif // COMPONENTS_TRACING_STARTUP_TRACING_H_
diff --git a/components/tracing/trace_config_file.cc b/components/tracing/trace_config_file.cc
new file mode 100644
index 0000000..e1cbc5c
--- /dev/null
+++ b/components/tracing/trace_config_file.cc
@@ -0,0 +1,140 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/tracing/trace_config_file.h"
+
+#include <string>
+
+#include "base/command_line.h"
+#include "base/files/file_util.h"
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
+#include "base/logging.h"
+#include "base/memory/singleton.h"
+#include "base/values.h"
+#include "components/tracing/tracing_switches.h"
+
+namespace tracing {
+
+namespace {
+
+// Maximum trace config file size that will be loaded, in bytes.
+const size_t kTraceConfigFileSizeLimit = 64 * 1024;
+
+// Trace config file path:
+// - Android: /data/local/chrome-trace-config.json
+// - Others: specified by --trace-config-file flag.
+#if defined(OS_ANDROID)
+const base::FilePath::CharType kAndroidTraceConfigFile[] =
+ FILE_PATH_LITERAL("/data/local/chrome-trace-config.json");
+#endif
+
+const base::FilePath::CharType kDefaultResultFile[] =
+ FILE_PATH_LITERAL("chrometrace.log");
+
+// String parameters that can be used to parse the trace config file content.
+const char kTraceConfigParam[] = "trace_config";
+const char kStartupDurationParam[] = "startup_duration";
+const char kResultFileParam[] = "result_file";
+
+} // namespace
+
+TraceConfigFile* TraceConfigFile::GetInstance() {
+ return Singleton<TraceConfigFile,
+ DefaultSingletonTraits<TraceConfigFile>>::get();
+}
+
+TraceConfigFile::TraceConfigFile()
+ : is_enabled_(false),
+ trace_config_(base::trace_event::TraceConfig()),
+ startup_duration_(0),
+ result_file_(kDefaultResultFile) {
+#if defined(OS_ANDROID)
+ base::FilePath trace_config_file(kAndroidTraceConfigFile);
+#else
+ const base::CommandLine& command_line =
+ *base::CommandLine::ForCurrentProcess();
+ if (!command_line.HasSwitch(switches::kTraceConfigFile) ||
+ command_line.HasSwitch(switches::kTraceStartup) ||
+ command_line.HasSwitch(switches::kTraceShutdown)) {
+ return;
+ }
+ base::FilePath trace_config_file =
+ command_line.GetSwitchValuePath(switches::kTraceConfigFile);
+#endif
+
+ if (trace_config_file.empty()) {
+ // If the trace config file path is not specified, trace Chrome with the
+ // default configuration for 5 sec.
+ startup_duration_ = 5;
+ is_enabled_ = true;
+ return;
+ }
+
+ if (!base::PathExists(trace_config_file))
+ return;
+
+ std::string trace_config_file_content;
+ if (!base::ReadFileToString(trace_config_file,
+ &trace_config_file_content,
+ kTraceConfigFileSizeLimit)) {
+ return;
+ }
+ is_enabled_ = ParseTraceConfigFileContent(trace_config_file_content);
+}
+
+TraceConfigFile::~TraceConfigFile() {
+}
+
+bool TraceConfigFile::ParseTraceConfigFileContent(std::string content) {
+ scoped_ptr<base::Value> value(base::JSONReader::Read(content));
+ if (!value || !value->IsType(base::Value::TYPE_DICTIONARY))
+ return false;
+
+ scoped_ptr<base::DictionaryValue> dict(
+ static_cast<base::DictionaryValue*>(value.release()));
+
+ base::DictionaryValue* trace_config_dict = NULL;
+ if (!dict->GetDictionary(kTraceConfigParam, &trace_config_dict))
+ return false;
+
+ std::string trace_config_str;
+ base::JSONWriter::Write(*trace_config_dict, &trace_config_str);
+ trace_config_ = base::trace_event::TraceConfig(trace_config_str);
+
+ if (!dict->GetInteger(kStartupDurationParam, &startup_duration_))
+ startup_duration_ = 0;
+
+ if (startup_duration_ < 0)
+ startup_duration_ = 0;
+
+ std::string result_file_str;
+ if (dict->GetString(kResultFileParam, &result_file_str))
+ result_file_ = base::FilePath().AppendASCII(result_file_str);
+
+ return true;
+}
+
+bool TraceConfigFile::IsEnabled() const {
+ return is_enabled_;
+}
+
+base::trace_event::TraceConfig TraceConfigFile::GetTraceConfig() const {
+ DCHECK(IsEnabled());
+ return trace_config_;
+}
+
+int TraceConfigFile::GetStartupDuration() const {
+ DCHECK(IsEnabled());
+ return startup_duration_;
+}
+
+#if !defined(OS_ANDROID)
+base::FilePath TraceConfigFile::GetResultFile() const {
+ DCHECK(IsEnabled());
+ return result_file_;
+}
+#endif
+
+} // namespace tracing
diff --git a/components/tracing/trace_config_file.h b/components/tracing/trace_config_file.h
new file mode 100644
index 0000000..273f9f1
--- /dev/null
+++ b/components/tracing/trace_config_file.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_TRACING_TRACE_CONFIG_FILE_H_
+#define COMPONENTS_TRACING_TRACE_CONFIG_FILE_H_
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/trace_event/trace_config.h"
+#include "components/tracing/tracing_export.h"
+
+template <typename Type> struct DefaultSingletonTraits;
+
+namespace tracing {
+
+// TraceConfigFile is a singleton that contains the configurations of tracing.
+// One can create a trace config file and use it to configure startup and/or
+// shutdown tracing.
+//
+// The trace config file should be JSON formated. One example is:
+// {
+// "trace_config": {
+// "record_mode": "record-until-full",
+// "included_categories": ["cc", "skia"]
+// },
+// "startup_duration": 5,
+// "result_file": "chrometrace.log"
+// }
+//
+// trace_config: The configuration of tracing. Please see the details in
+// base/trace_event/trace_config.h.
+//
+// startup_duration: The duration for startup tracing in terms of seconds.
+// Tracing will stop automatically after the duration. If this
+// value is not specified, the duration is 0 and one needs
+// to stop tracing by other ways, e.g., by DevTools, or get
+// the result file after shutting the browser down.
+//
+// result_file: The file that contains the trace log. The default result
+// file path is chrometrace.log. Chrome will dump the trace
+// log to this file
+// 1) after startup_duration if it is specified;
+// 2) or after browser shutdown if startup duration is 0.
+// One can also stop tracing and get the result by other ways,
+// e.g., by DevTools. In that case, the trace log will not be
+// saved to this file.
+// Notice: This is not supported on Android. The result file
+// path will be generated by tracing controller.
+//
+// The trace config file can be specified by the --trace-config-file flag on
+// most platforms except on Android, e.g., --trace-config-file=path/to/file/.
+// This flag should not be used with --trace-startup or --trace-shutdown. If
+// those two flags are used, --trace-config-file flag will be ignored. If the
+// --trace-config-file flag is used without the file path, Chrome will do
+// startup tracing with 5 seconds' startup duration.
+//
+// On Android, Chrome does not read the --trace-config-file flag, because not
+// all Chrome based browsers read customized flag, e.g., Android WebView. Chrome
+// on Android reads from a fixed file location:
+// /data/local/chrome-trace-config.json
+// If this file exists, Chrome will start tracing according to the configuration
+// specified in the file, otherwise, Chrome will not start tracing.
+class TRACING_EXPORT TraceConfigFile {
+ public:
+ static TraceConfigFile* GetInstance();
+
+ bool IsEnabled() const;
+ base::trace_event::TraceConfig GetTraceConfig() const;
+ int GetStartupDuration() const;
+#if !defined(OS_ANDROID)
+ base::FilePath GetResultFile() const;
+#endif
+
+ private:
+ // This allows constructor and destructor to be private and usable only
+ // by the Singleton class.
+ friend struct DefaultSingletonTraits<TraceConfigFile>;
+ TraceConfigFile();
+ ~TraceConfigFile();
+
+ bool ParseTraceConfigFileContent(std::string content);
+
+ bool is_enabled_;
+ base::trace_event::TraceConfig trace_config_;
+ int startup_duration_;
+ base::FilePath result_file_;
+
+ DISALLOW_COPY_AND_ASSIGN(TraceConfigFile);
+};
+
+} // namespace tracing
+
+#endif // COMPONENTS_TRACING_TRACE_CONFIG_FILE_H_
diff --git a/components/tracing/trace_config_file_unittest.cc b/components/tracing/trace_config_file_unittest.cc
new file mode 100644
index 0000000..d62c4d4
--- /dev/null
+++ b/components/tracing/trace_config_file_unittest.cc
@@ -0,0 +1,220 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/at_exit.h"
+#include "base/command_line.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "components/tracing/trace_config_file.h"
+#include "components/tracing/tracing_switches.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace tracing {
+
+namespace {
+
+const char kTraceConfig[] =
+ "{"
+ "\"enable_argument_filter\":true,"
+ "\"enable_sampling\":true,"
+ "\"enable_systrace\":true,"
+ "\"excluded_categories\":[\"excluded\",\"exc_pattern*\"],"
+ "\"included_categories\":[\"included\","
+ "\"inc_pattern*\","
+ "\"disabled-by-default-cc\"],"
+ "\"record_mode\":\"record-continuously\","
+ "\"synthetic_delays\":[\"test.Delay1;16\",\"test.Delay2;32\"]"
+ "}";
+
+std::string GetTraceConfigFileContent(std::string trace_config,
+ std::string startup_duration,
+ std::string result_file) {
+ std::string content = "{";
+ if (!trace_config.empty())
+ content += "\"trace_config\":" + trace_config;
+
+ if (!startup_duration.empty()) {
+ if (content != "{")
+ content += ",";
+ content += "\"startup_duration\":" + startup_duration;
+ }
+
+ if (!result_file.empty()) {
+ if (content != "{")
+ content += ",";
+ content += "\"result_file\":\"" + result_file + "\"";
+ }
+
+ content += "}";
+ return content;
+}
+
+} // namespace
+
+TEST(TraceConfigFileTest, TraceStartupEnabled) {
+ base::ShadowingAtExitManager sem;
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kTraceStartup);
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kTraceConfigFile);
+
+ EXPECT_FALSE(TraceConfigFile::GetInstance()->IsEnabled());
+}
+
+TEST(TraceConfigFileTest, TraceShutdownEnabled) {
+ base::ShadowingAtExitManager sem;
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kTraceShutdown);
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kTraceConfigFile);
+
+ EXPECT_FALSE(TraceConfigFile::GetInstance()->IsEnabled());
+}
+
+TEST(TraceConfigFileTest, TraceConfigFileNotEnabled) {
+ base::ShadowingAtExitManager sem;
+ EXPECT_FALSE(TraceConfigFile::GetInstance()->IsEnabled());
+}
+
+TEST(TraceConfigFileTest, TraceConfigFileEnabledWithoutPath) {
+ base::ShadowingAtExitManager sem;
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kTraceConfigFile);
+
+ ASSERT_TRUE(TraceConfigFile::GetInstance()->IsEnabled());
+ EXPECT_EQ(base::trace_event::TraceConfig().ToString(),
+ TraceConfigFile::GetInstance()->GetTraceConfig().ToString());
+ EXPECT_EQ(5, TraceConfigFile::GetInstance()->GetStartupDuration());
+ EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("chrometrace.log")),
+ TraceConfigFile::GetInstance()->GetResultFile());
+}
+
+TEST(TraceConfigFileTest, TraceConfigFileEnabledWithInvalidPath) {
+ base::ShadowingAtExitManager sem;
+ base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
+ switches::kTraceConfigFile,
+ base::FilePath(FILE_PATH_LITERAL("invalid-trace-config-file-path")));
+
+ EXPECT_FALSE(TraceConfigFile::GetInstance()->IsEnabled());
+}
+
+TEST(TraceConfigFileTest, ValidContent) {
+ base::ShadowingAtExitManager sem;
+ std::string content = GetTraceConfigFileContent(
+ kTraceConfig, "10", "trace_result_file.log");
+
+ base::FilePath trace_config_file;
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_dir.path(), &trace_config_file));
+ ASSERT_NE(-1, base::WriteFile(
+ trace_config_file, content.c_str(), (int)content.length()));
+ base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
+ switches::kTraceConfigFile, trace_config_file);
+
+ ASSERT_TRUE(TraceConfigFile::GetInstance()->IsEnabled());
+ EXPECT_STREQ(
+ kTraceConfig,
+ TraceConfigFile::GetInstance()->GetTraceConfig().ToString().c_str());
+ EXPECT_EQ(10, TraceConfigFile::GetInstance()->GetStartupDuration());
+ EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("trace_result_file.log")),
+ TraceConfigFile::GetInstance()->GetResultFile());
+}
+
+TEST(TraceConfigFileTest, ValidContentWithOnlyTraceConfig) {
+ base::ShadowingAtExitManager sem;
+ std::string content = GetTraceConfigFileContent(kTraceConfig, "", "");
+
+ base::FilePath trace_config_file;
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_dir.path(), &trace_config_file));
+ ASSERT_NE(-1, base::WriteFile(
+ trace_config_file, content.c_str(), (int)content.length()));
+ base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
+ switches::kTraceConfigFile, trace_config_file);
+
+ ASSERT_TRUE(TraceConfigFile::GetInstance()->IsEnabled());
+ EXPECT_STREQ(
+ kTraceConfig,
+ TraceConfigFile::GetInstance()->GetTraceConfig().ToString().c_str());
+ EXPECT_EQ(0, TraceConfigFile::GetInstance()->GetStartupDuration());
+ EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("chrometrace.log")),
+ TraceConfigFile::GetInstance()->GetResultFile());
+}
+
+TEST(TraceConfigFileTest, ContentWithNegtiveDuration) {
+ base::ShadowingAtExitManager sem;
+ std::string content = GetTraceConfigFileContent(kTraceConfig, "-1", "");
+
+ base::FilePath trace_config_file;
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_dir.path(), &trace_config_file));
+ ASSERT_NE(-1, base::WriteFile(
+ trace_config_file, content.c_str(), (int)content.length()));
+ base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
+ switches::kTraceConfigFile, trace_config_file);
+
+ ASSERT_TRUE(TraceConfigFile::GetInstance()->IsEnabled());
+ EXPECT_STREQ(
+ kTraceConfig,
+ TraceConfigFile::GetInstance()->GetTraceConfig().ToString().c_str());
+ EXPECT_EQ(0, TraceConfigFile::GetInstance()->GetStartupDuration());
+ EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("chrometrace.log")),
+ TraceConfigFile::GetInstance()->GetResultFile());
+}
+
+TEST(TraceConfigFileTest, ContentWithoutTraceConfig) {
+ base::ShadowingAtExitManager sem;
+ std::string content = GetTraceConfigFileContent(
+ "", "10", "trace_result_file.log");
+
+ base::FilePath trace_config_file;
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_dir.path(), &trace_config_file));
+ ASSERT_NE(-1, base::WriteFile(
+ trace_config_file, content.c_str(), (int)content.length()));
+ base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
+ switches::kTraceConfigFile, trace_config_file);
+
+ EXPECT_FALSE(TraceConfigFile::GetInstance()->IsEnabled());
+}
+
+TEST(TraceConfigFileTest, InvalidContent) {
+ base::ShadowingAtExitManager sem;
+ std::string content = "invalid trace config file content";
+
+ base::FilePath trace_config_file;
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_dir.path(), &trace_config_file));
+ ASSERT_NE(-1, base::WriteFile(
+ trace_config_file, content.c_str(), (int)content.length()));
+ base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
+ switches::kTraceConfigFile, trace_config_file);
+
+ EXPECT_FALSE(TraceConfigFile::GetInstance()->IsEnabled());
+}
+
+TEST(TraceConfigFileTest, EmptyContent) {
+ base::ShadowingAtExitManager sem;
+ base::FilePath trace_config_file;
+ base::ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ base::CreateTemporaryFileInDir(temp_dir.path(), &trace_config_file));
+ base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
+ switches::kTraceConfigFile, trace_config_file);
+
+ EXPECT_FALSE(TraceConfigFile::GetInstance()->IsEnabled());
+}
+
+} // namespace tracing
diff --git a/components/tracing/tracing_switches.cc b/components/tracing/tracing_switches.cc
index fcec5ee..ba3c1b1 100644
--- a/components/tracing/tracing_switches.cc
+++ b/components/tracing/tracing_switches.cc
@@ -6,6 +6,10 @@
namespace switches {
+// Causes TRACE_EVENT flags to be recorded from startup.
+// This flag will be ignored if --trace-startup or --trace-shutdown is provided.
+const char kTraceConfigFile[] = "trace-config-file";
+
// Causes TRACE_EVENT flags to be recorded beginning with shutdown. Optionally,
// can specify the specific trace categories to include (e.g.
// --trace-shutdown=base,net) otherwise, all events are recorded.
diff --git a/components/tracing/tracing_switches.h b/components/tracing/tracing_switches.h
index dba13da..263a49b 100644
--- a/components/tracing/tracing_switches.h
+++ b/components/tracing/tracing_switches.h
@@ -9,6 +9,7 @@
namespace switches {
+TRACING_EXPORT extern const char kTraceConfigFile[];
TRACING_EXPORT extern const char kTraceShutdown[];
TRACING_EXPORT extern const char kTraceShutdownFile[];
TRACING_EXPORT extern const char kTraceStartup[];