diff options
author | dsinclair@chromium.org <dsinclair@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-23 02:09:53 +0000 |
---|---|---|
committer | dsinclair@chromium.org <dsinclair@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-23 02:09:53 +0000 |
commit | dcc7837317b2f78398461ae1cc78e14780222639 (patch) | |
tree | 837804f3c4ec78738648199193dd9948498bfa25 | |
parent | 9b5f0a4b60e2139bb6e80947f93f59164bb1ee17 (diff) | |
download | chromium_src-dcc7837317b2f78398461ae1cc78e14780222639.zip chromium_src-dcc7837317b2f78398461ae1cc78e14780222639.tar.gz chromium_src-dcc7837317b2f78398461ae1cc78e14780222639.tar.bz2 |
Add a mode flag to the tracing framework.
The mode is provided when SetEnabled is called. Currently there
is only one mode which is the trace until buffer is full mode.
We will be adding a continuous tracing mode which this will support.
BUG=156025
Review URL: https://chromiumcodereview.appspot.com/12302036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@184258 0039d316-1c4b-4281-b951-d872f2087c98
20 files changed, 219 insertions, 70 deletions
diff --git a/base/debug/trace_event_impl.cc b/base/debug/trace_event_impl.cc index cbcf54b..5eafd52 100644 --- a/base/debug/trace_event_impl.cc +++ b/base/debug/trace_event_impl.cc @@ -14,6 +14,7 @@ #include "base/memory/singleton.h" #include "base/process_util.h" #include "base/stl_util.h" +#include "base/string_split.h" #include "base/string_util.h" #include "base/stringprintf.h" #include "base/strings/string_tokenizer.h" @@ -72,6 +73,8 @@ int g_category_index = 3; // skip initial 3 categories LazyInstance<ThreadLocalPointer<const char> >::Leaky g_current_thread_name = LAZY_INSTANCE_INITIALIZER; +const char kRecordUntilFull[] = "record-until-full"; + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -348,10 +351,37 @@ TraceLog* TraceLog::GetInstance() { return Singleton<TraceLog, StaticMemorySingletonTraits<TraceLog> >::get(); } +// static +// Note, if you add more options here you also need to update: +// content/browser/devtools/devtools_tracing_handler:TraceOptionsFromString +TraceLog::Options TraceLog::TraceOptionsFromString(const std::string& options) { + std::vector<std::string> split; + base::SplitString(options, ',', &split); + int ret = 0; + for (std::vector<std::string>::iterator iter = split.begin(); + iter != split.end(); + ++iter) { + if (*iter == kRecordUntilFull) { + ret |= RECORD_UNTIL_FULL; + } else { + NOTREACHED(); // Unknown option provided. + } + } + // Check to see if any RECORD_* options are set, and if none, then provide + // a default. + // TODO(dsinclair): Remove this comment when we have more then one RECORD_* + // flag and the code's structure is then sensible. + if (!(ret & RECORD_UNTIL_FULL)) + ret |= RECORD_UNTIL_FULL; // Default when no options are specified. + + return static_cast<Options>(ret); +} + TraceLog::TraceLog() : enable_count_(0), dispatching_to_observer_list_(false), - watch_category_(NULL) { + watch_category_(NULL), + trace_options_(RECORD_UNTIL_FULL) { // Trace is enabled or disabled on one thread while other threads are // accessing the enabled flag. We don't care whether edge-case events are // traced or not, so we allow races on the enabled flag to keep the trace @@ -478,10 +508,16 @@ void TraceLog::GetKnownCategories(std::vector<std::string>* categories) { } void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, - const std::vector<std::string>& excluded_categories) { + const std::vector<std::string>& excluded_categories, + Options options) { AutoLock lock(lock_); if (enable_count_++ > 0) { + if (options != trace_options_) { + DLOG(ERROR) << "Attemting to re-enable tracing with a different " + << "set of options."; + } + // Tracing is already enabled, so just merge in enabled categories. // We only expand the set of enabled categories upon nested SetEnable(). if (!included_categories_.empty() && !included_categories.empty()) { @@ -497,6 +533,7 @@ void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, } return; } + trace_options_ = options; if (dispatching_to_observer_list_) { DLOG(ERROR) << @@ -520,7 +557,7 @@ void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); } -void TraceLog::SetEnabled(const std::string& categories) { +void TraceLog::SetEnabled(const std::string& categories, Options options) { std::vector<std::string> included, excluded; // Tokenize list of categories, delimited by ','. StringTokenizer tokens(categories, ","); @@ -538,7 +575,7 @@ void TraceLog::SetEnabled(const std::string& categories) { else excluded.push_back(category); } - SetEnabled(included, excluded); + SetEnabled(included, excluded, options); } void TraceLog::GetEnabledTraceCategories( @@ -577,9 +614,9 @@ void TraceLog::SetDisabled() { AddThreadNameMetadataEvents(); } -void TraceLog::SetEnabled(bool enabled) { +void TraceLog::SetEnabled(bool enabled, Options options) { if (enabled) - SetEnabled(std::vector<std::string>(), std::vector<std::string>()); + SetEnabled(std::vector<std::string>(), std::vector<std::string>(), options); else SetDisabled(); } diff --git a/base/debug/trace_event_impl.h b/base/debug/trace_event_impl.h index f152b0a4..c73fbcb 100644 --- a/base/debug/trace_event_impl.h +++ b/base/debug/trace_event_impl.h @@ -157,7 +157,6 @@ class BASE_EXPORT TraceResultBuffer { bool append_comma_; }; - class BASE_EXPORT TraceLog { public: // Notification is a mask of one or more of the following events. @@ -170,8 +169,17 @@ class BASE_EXPORT TraceLog { EVENT_WATCH_NOTIFICATION = 1 << 1 }; + // Options determines how the trace buffer stores data. + enum Options { + RECORD_UNTIL_FULL = 1 << 0 + }; + static TraceLog* GetInstance(); + // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if + // the string does not provide valid options. + static Options TraceOptionsFromString(const std::string& str); + // Get set of known categories. This can change as new code paths are reached. // The known categories are inserted into |categories|. void GetKnownCategories(std::vector<std::string>* categories); @@ -185,7 +193,8 @@ class BASE_EXPORT TraceLog { // Else if excluded_categories is non-empty, everything but those are traced. // Wildcards * and ? are supported (see MatchPattern in string_util.h). void SetEnabled(const std::vector<std::string>& included_categories, - const std::vector<std::string>& excluded_categories); + const std::vector<std::string>& excluded_categories, + Options options); // |categories| is a comma-delimited list of category wildcards. // A category can have an optional '-' prefix to make it an excluded category. @@ -195,17 +204,19 @@ class BASE_EXPORT TraceLog { // Example: SetEnabled("test_MyTest*"); // Example: SetEnabled("test_MyTest*,test_OtherStuff"); // Example: SetEnabled("-excluded_category1,-excluded_category2"); - void SetEnabled(const std::string& categories); + void SetEnabled(const std::string& categories, Options options); // Retieves the categories set via a prior call to SetEnabled(). Only // meaningful if |IsEnabled()| is true. void GetEnabledTraceCategories(std::vector<std::string>* included_out, std::vector<std::string>* excluded_out); + Options trace_options() const { return trace_options_; } + // Disable tracing for all categories. void SetDisabled(); // Helper method to enable/disable tracing for all categories. - void SetEnabled(bool enabled); + void SetEnabled(bool enabled, Options options); bool IsEnabled() { return !!enable_count_; } #if defined(OS_ANDROID) @@ -400,6 +411,8 @@ class BASE_EXPORT TraceLog { const unsigned char* watch_category_; std::string watch_event_name_; + Options trace_options_; + DISALLOW_COPY_AND_ASSIGN(TraceLog); }; diff --git a/base/debug/trace_event_unittest.cc b/base/debug/trace_event_unittest.cc index 78bcc23..fd6bbd2 100644 --- a/base/debug/trace_event_unittest.cc +++ b/base/debug/trace_event_unittest.cc @@ -73,7 +73,8 @@ class TraceEventTestFixture : public testing::Test { void BeginTrace() { event_watch_notification_ = 0; - TraceLog::GetInstance()->SetEnabled(std::string("*")); + TraceLog::GetInstance()->SetEnabled(std::string("*"), + TraceLog::RECORD_UNTIL_FULL); } void EndTraceAndFlush() { @@ -714,7 +715,7 @@ void HighResSleepForTraceTest(base::TimeDelta elapsed) { // Simple Test for emitting data and validating it was received. TEST_F(TraceEventTestFixture, DataCaptured) { ManualTestSetUp(); - TraceLog::GetInstance()->SetEnabled(true); + TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); TraceWithAllMacroVariants(NULL); @@ -738,18 +739,18 @@ TEST_F(TraceEventTestFixture, EnabledObserverFiresOnEnable) { EXPECT_CALL(observer, OnTraceLogWillEnable()) .Times(1); - TraceLog::GetInstance()->SetEnabled(true); + TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); testing::Mock::VerifyAndClear(&observer); // Cleanup. TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer); - TraceLog::GetInstance()->SetEnabled(false); + TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL); } TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnSecondEnable) { ManualTestSetUp(); - TraceLog::GetInstance()->SetEnabled(true); + TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); testing::StrictMock<MockEnabledStateChangedObserver> observer; TraceLog::GetInstance()->AddEnabledStateObserver(&observer); @@ -758,20 +759,20 @@ TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnSecondEnable) { .Times(0); EXPECT_CALL(observer, OnTraceLogWillDisable()) .Times(0); - TraceLog::GetInstance()->SetEnabled(true); + TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); testing::Mock::VerifyAndClear(&observer); // Cleanup. TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer); - TraceLog::GetInstance()->SetEnabled(false); - TraceLog::GetInstance()->SetEnabled(false); + TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL); } TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnNestedDisable) { ManualTestSetUp(); - TraceLog::GetInstance()->SetEnabled(true); - TraceLog::GetInstance()->SetEnabled(true); + TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); testing::StrictMock<MockEnabledStateChangedObserver> observer; TraceLog::GetInstance()->AddEnabledStateObserver(&observer); @@ -780,25 +781,25 @@ TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnNestedDisable) { .Times(0); EXPECT_CALL(observer, OnTraceLogWillDisable()) .Times(0); - TraceLog::GetInstance()->SetEnabled(false); + TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL); testing::Mock::VerifyAndClear(&observer); // Cleanup. TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer); - TraceLog::GetInstance()->SetEnabled(false); + TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL); } TEST_F(TraceEventTestFixture, EnabledObserverFiresOnDisable) { ManualTestSetUp(); - TraceLog::GetInstance()->SetEnabled(true); + TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); MockEnabledStateChangedObserver observer; TraceLog::GetInstance()->AddEnabledStateObserver(&observer); EXPECT_CALL(observer, OnTraceLogWillDisable()) .Times(1); - TraceLog::GetInstance()->SetEnabled(false); + TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL); testing::Mock::VerifyAndClear(&observer); // Cleanup. @@ -834,7 +835,8 @@ TEST_F(TraceEventTestFixture, Categories) { Clear(); included_categories.clear(); included_categories.push_back("not_found823564786"); - TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories); + TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories, + TraceLog::RECORD_UNTIL_FULL); TRACE_EVENT_INSTANT0("cat1", "name"); TRACE_EVENT_INSTANT0("cat2", "name"); EndTraceAndFlush(); @@ -844,7 +846,8 @@ TEST_F(TraceEventTestFixture, Categories) { Clear(); included_categories.clear(); included_categories.push_back("inc"); - TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories); + TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories, + TraceLog::RECORD_UNTIL_FULL); TRACE_EVENT_INSTANT0("inc", "name"); TRACE_EVENT_INSTANT0("inc2", "name"); EndTraceAndFlush(); @@ -856,7 +859,8 @@ TEST_F(TraceEventTestFixture, Categories) { included_categories.clear(); included_categories.push_back("inc_wildcard_*"); included_categories.push_back("inc_wildchar_?_end"); - TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories); + TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories, + TraceLog::RECORD_UNTIL_FULL); TRACE_EVENT_INSTANT0("inc_wildcard_abc", "included"); TRACE_EVENT_INSTANT0("inc_wildcard_", "included"); TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "included"); @@ -875,7 +879,8 @@ TEST_F(TraceEventTestFixture, Categories) { Clear(); excluded_categories.clear(); excluded_categories.push_back("not_found823564786"); - TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories); + TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories, + TraceLog::RECORD_UNTIL_FULL); TRACE_EVENT_INSTANT0("cat1", "name"); TRACE_EVENT_INSTANT0("cat2", "name"); EndTraceAndFlush(); @@ -886,7 +891,8 @@ TEST_F(TraceEventTestFixture, Categories) { Clear(); excluded_categories.clear(); excluded_categories.push_back("inc"); - TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories); + TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories, + TraceLog::RECORD_UNTIL_FULL); TRACE_EVENT_INSTANT0("inc", "name"); TRACE_EVENT_INSTANT0("inc2", "name"); EndTraceAndFlush(); @@ -898,7 +904,8 @@ TEST_F(TraceEventTestFixture, Categories) { excluded_categories.clear(); excluded_categories.push_back("inc_wildcard_*"); excluded_categories.push_back("inc_wildchar_?_end"); - TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories); + TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories, + TraceLog::RECORD_UNTIL_FULL); TRACE_EVENT_INSTANT0("inc_wildcard_abc", "not_inc"); TRACE_EVENT_INSTANT0("inc_wildcard_", "not_inc"); TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "not_inc"); @@ -1431,17 +1438,17 @@ TEST_F(TraceEventTestFixture, TraceEnableDisable) { ManualTestSetUp(); TraceLog* trace_log = TraceLog::GetInstance(); - trace_log->SetEnabled(std::string()); + trace_log->SetEnabled(std::string(), TraceLog::RECORD_UNTIL_FULL); EXPECT_TRUE(trace_log->IsEnabled()); trace_log->SetDisabled(); EXPECT_FALSE(trace_log->IsEnabled()); - trace_log->SetEnabled(true); + trace_log->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); EXPECT_TRUE(trace_log->IsEnabled()); const std::vector<std::string> empty; - trace_log->SetEnabled(empty, empty); + trace_log->SetEnabled(empty, empty, TraceLog::RECORD_UNTIL_FULL); EXPECT_TRUE(trace_log->IsEnabled()); - trace_log->SetEnabled(false); + trace_log->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL); EXPECT_TRUE(trace_log->IsEnabled()); trace_log->SetDisabled(); EXPECT_FALSE(trace_log->IsEnabled()); @@ -1451,14 +1458,14 @@ TEST_F(TraceEventTestFixture, TraceCategoriesAfterNestedEnable) { ManualTestSetUp(); TraceLog* trace_log = TraceLog::GetInstance(); - trace_log->SetEnabled(std::string("foo,bar")); + trace_log->SetEnabled(std::string("foo,bar"), TraceLog::RECORD_UNTIL_FULL); EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo")); EXPECT_TRUE(*trace_log->GetCategoryEnabled("bar")); EXPECT_FALSE(*trace_log->GetCategoryEnabled("baz")); - trace_log->SetEnabled(std::string("foo2")); + trace_log->SetEnabled(std::string("foo2"), TraceLog::RECORD_UNTIL_FULL); EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo2")); EXPECT_FALSE(*trace_log->GetCategoryEnabled("baz")); - trace_log->SetEnabled(std::string("")); + trace_log->SetEnabled(std::string(""), TraceLog::RECORD_UNTIL_FULL); EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo")); EXPECT_TRUE(*trace_log->GetCategoryEnabled("baz")); trace_log->SetDisabled(); @@ -1467,10 +1474,10 @@ TEST_F(TraceEventTestFixture, TraceCategoriesAfterNestedEnable) { EXPECT_FALSE(*trace_log->GetCategoryEnabled("foo")); EXPECT_FALSE(*trace_log->GetCategoryEnabled("baz")); - trace_log->SetEnabled(std::string("-foo,-bar")); + trace_log->SetEnabled(std::string("-foo,-bar"), TraceLog::RECORD_UNTIL_FULL); EXPECT_FALSE(*trace_log->GetCategoryEnabled("foo")); EXPECT_TRUE(*trace_log->GetCategoryEnabled("baz")); - trace_log->SetEnabled(std::string("moo")); + trace_log->SetEnabled(std::string("moo"), TraceLog::RECORD_UNTIL_FULL); EXPECT_TRUE(*trace_log->GetCategoryEnabled("baz")); EXPECT_TRUE(*trace_log->GetCategoryEnabled("moo")); EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo")); @@ -1478,5 +1485,14 @@ TEST_F(TraceEventTestFixture, TraceCategoriesAfterNestedEnable) { trace_log->SetDisabled(); } +TEST_F(TraceEventTestFixture, TraceOptionsParsing) { + ManualTestSetUp(); + + EXPECT_EQ(TraceLog::RECORD_UNTIL_FULL, TraceLog::TraceOptionsFromString("")); + + EXPECT_EQ(TraceLog::RECORD_UNTIL_FULL, + TraceLog::TraceOptionsFromString("record-until-full")); +} + } // namespace debug } // namespace base diff --git a/base/test/trace_event_analyzer_unittest.cc b/base/test/trace_event_analyzer_unittest.cc index eca2b70..6004341 100644 --- a/base/test/trace_event_analyzer_unittest.cc +++ b/base/test/trace_event_analyzer_unittest.cc @@ -39,11 +39,15 @@ void TraceEventAnalyzerTest::OnTraceDataCollected( void TraceEventAnalyzerTest::BeginTracing() { output_.json_output.clear(); buffer_.Start(); - base::debug::TraceLog::GetInstance()->SetEnabled(true); + base::debug::TraceLog::GetInstance()->SetEnabled( + true, + base::debug::TraceLog::RECORD_UNTIL_FULL); } void TraceEventAnalyzerTest::EndTracing() { - base::debug::TraceLog::GetInstance()->SetEnabled(false); + base::debug::TraceLog::GetInstance()->SetEnabled( + false, + base::debug::TraceLog::RECORD_UNTIL_FULL); base::debug::TraceLog::GetInstance()->Flush( base::Bind(&TraceEventAnalyzerTest::OnTraceDataCollected, base::Unretained(this))); diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index 7503ae2..2a8e07e 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -770,7 +770,10 @@ void AutomationProvider::JavaScriptStressTestControl(int tab_handle, void AutomationProvider::BeginTracing(const std::string& categories, bool* success) { tracing_data_.trace_output.clear(); - *success = TraceController::GetInstance()->BeginTracing(this, categories); + *success = TraceController::GetInstance()->BeginTracing( + this, + categories, + base::debug::TraceLog::RECORD_UNTIL_FULL); } void AutomationProvider::EndTracing(IPC::Message* reply_message) { diff --git a/chrome/test/base/tracing.cc b/chrome/test/base/tracing.cc index 9ab978d..b3a28d0 100644 --- a/chrome/test/base/tracing.cc +++ b/chrome/test/base/tracing.cc @@ -30,7 +30,7 @@ class InProcessTraceController : public content::TraceSubscriber { bool BeginTracing(const std::string& categories) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); return content::TraceController::GetInstance()->BeginTracing( - this, categories); + this, categories, base::debug::TraceLog::RECORD_UNTIL_FULL); } bool BeginTracingWithWatch(const std::string& categories, diff --git a/components/tracing/child_trace_message_filter.cc b/components/tracing/child_trace_message_filter.cc index 161c778..1b001a7 100644 --- a/components/tracing/child_trace_message_filter.cc +++ b/components/tracing/child_trace_message_filter.cc @@ -48,7 +48,8 @@ ChildTraceMessageFilter::~ChildTraceMessageFilter() {} void ChildTraceMessageFilter::OnBeginTracing( const std::vector<std::string>& included_categories, const std::vector<std::string>& excluded_categories, - base::TimeTicks browser_time) { + base::TimeTicks browser_time, + int options) { #if defined(__native_client__) // NaCl and system times are offset by a bit, so subtract some time from // the captured timestamps. The value might be off by a bit due to messaging @@ -57,8 +58,10 @@ void ChildTraceMessageFilter::OnBeginTracing( browser_time; TraceLog::GetInstance()->SetTimeOffset(time_offset); #endif - TraceLog::GetInstance()->SetEnabled(included_categories, - excluded_categories); + TraceLog::GetInstance()->SetEnabled( + included_categories, + excluded_categories, + static_cast<base::debug::TraceLog::Options>(options)); } void ChildTraceMessageFilter::OnEndTracing() { diff --git a/components/tracing/child_trace_message_filter.h b/components/tracing/child_trace_message_filter.h index e4802ba..7d85627 100644 --- a/components/tracing/child_trace_message_filter.h +++ b/components/tracing/child_trace_message_filter.h @@ -30,7 +30,8 @@ class ChildTraceMessageFilter : public IPC::ChannelProxy::MessageFilter { // Message handlers. void OnBeginTracing(const std::vector<std::string>& included_categories, const std::vector<std::string>& excluded_categories, - base::TimeTicks browser_time); + base::TimeTicks browser_time, + int mode); void OnEndTracing(); void OnGetTraceBufferPercentFull(); void OnSetWatchEvent(const std::string& category_name, diff --git a/components/tracing/tracing_messages.h b/components/tracing/tracing_messages.h index 792c476..fd15c21 100644 --- a/components/tracing/tracing_messages.h +++ b/components/tracing/tracing_messages.h @@ -16,10 +16,11 @@ #define IPC_MESSAGE_START TracingMsgStart // Sent to all child processes to enable trace event recording. -IPC_MESSAGE_CONTROL3(TracingMsg_BeginTracing, +IPC_MESSAGE_CONTROL4(TracingMsg_BeginTracing, std::vector<std::string> /* included_categories */, std::vector<std::string> /* excluded_categories */, - base::TimeTicks /* browser_time */) + base::TimeTicks /* browser_time */, + int /* base::debug::TraceLog::Options */) // Sent to all child processes to disable trace event recording. IPC_MESSAGE_CONTROL0(TracingMsg_EndTracing) diff --git a/content/app/android/library_loader_hooks.cc b/content/app/android/library_loader_hooks.cc index 4794da1..f9607c1 100644 --- a/content/app/android/library_loader_hooks.cc +++ b/content/app/android/library_loader_hooks.cc @@ -43,7 +43,8 @@ static jint LibraryLoadedOnMainThread(JNIEnv* env, jclass clazz, if (command_line->HasSwitch(switches::kTraceStartup)) { base::debug::TraceLog::GetInstance()->SetEnabled( - command_line->GetSwitchValueASCII(switches::kTraceStartup)); + command_line->GetSwitchValueASCII(switches::kTraceStartup), + base::debug::TraceLog::RECORD_UNTIL_FULL); } // Can only use event tracing after setting up the command line. diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc index ce1f5c9..cfe320a 100644 --- a/content/app/content_main_runner.cc +++ b/content/app/content_main_runner.cc @@ -636,7 +636,8 @@ class ContentMainRunnerImpl : public ContentMainRunner { // ignored. if (command_line.HasSwitch(switches::kTraceStartup)) { base::debug::TraceLog::GetInstance()->SetEnabled( - command_line.GetSwitchValueASCII(switches::kTraceStartup)); + command_line.GetSwitchValueASCII(switches::kTraceStartup), + base::debug::TraceLog::RECORD_UNTIL_FULL); } #if defined(OS_MACOSX) && !defined(OS_IOS) diff --git a/content/browser/android/tracing_intent_handler.cc b/content/browser/android/tracing_intent_handler.cc index 5935a78..f26f5b3 100644 --- a/content/browser/android/tracing_intent_handler.cc +++ b/content/browser/android/tracing_intent_handler.cc @@ -16,7 +16,10 @@ TracingIntentHandler* g_trace_intent_handler = NULL; TracingIntentHandler::TracingIntentHandler(const base::FilePath& path) : TraceSubscriberStdio(path) { - TraceController::GetInstance()->BeginTracing(this, std::string("-test*")); + TraceController::GetInstance()->BeginTracing( + this, + std::string("-test*"), + base::debug::TraceLog::RECORD_UNTIL_FULL); } TracingIntentHandler::~TracingIntentHandler() { diff --git a/content/browser/devtools/devtools_tracing_handler.cc b/content/browser/devtools/devtools_tracing_handler.cc index 87ae552..9451fe8 100644 --- a/content/browser/devtools/devtools_tracing_handler.cc +++ b/content/browser/devtools/devtools_tracing_handler.cc @@ -8,6 +8,7 @@ #include "base/callback.h" #include "base/json/json_writer.h" #include "base/location.h" +#include "base/string_split.h" #include "base/values.h" #include "content/browser/devtools/devtools_http_handler_impl.h" #include "content/public/browser/trace_controller.h" @@ -25,6 +26,9 @@ const char kTracingDataCollected[] = "Tracing.dataCollected"; const char kCategoriesParam[] = "categories"; +const char kTraceOptionsParam[] = "trace-options"; +const char kRecordUntilFull[] = "record-until-full"; + } // namespace const char DevToolsTracingHandler::kDomain[] = "Tracing"; @@ -56,13 +60,42 @@ void DevToolsTracingHandler::OnTraceDataCollected( } } +// Note, if you add more options here you also need to update: +// base/debug/trace_event_impl:TraceOptionsFromString +base::debug::TraceLog::Options DevToolsTracingHandler::TraceOptionsFromString( + const std::string& options) { + std::vector<std::string> split; + std::vector<std::string>::iterator iter; + int ret = 0; + + base::SplitString(options, ',', &split); + for (iter = split.begin(); iter != split.end(); ++iter) { + if (*iter == kRecordUntilFull) { + ret |= base::debug::TraceLog::RECORD_UNTIL_FULL; + } + } + if (ret == 0) + ret = base::debug::TraceLog::RECORD_UNTIL_FULL; + + return static_cast<base::debug::TraceLog::Options>(ret); +} + scoped_ptr<DevToolsProtocol::Response> DevToolsTracingHandler::OnStart(DevToolsProtocol::Command* command) { std::string categories; base::DictionaryValue* params = command->params(); if (params && params->HasKey(kCategoriesParam)) params->GetString(kCategoriesParam, &categories); - TraceController::GetInstance()->BeginTracing(this, categories); + + base::debug::TraceLog::Options options = + base::debug::TraceLog::RECORD_UNTIL_FULL; + if (params && params->HasKey(kTraceOptionsParam)) { + std::string options_param; + params->GetString(kTraceOptionsParam, &options_param); + options = TraceOptionsFromString(options_param); + } + + TraceController::GetInstance()->BeginTracing(this, categories, options); is_running_ = true; return command->SuccessResponse(NULL); } diff --git a/content/browser/devtools/devtools_tracing_handler.h b/content/browser/devtools/devtools_tracing_handler.h index 2d9ed52..86ddf00 100644 --- a/content/browser/devtools/devtools_tracing_handler.h +++ b/content/browser/devtools/devtools_tracing_handler.h @@ -5,6 +5,7 @@ #ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TRACING_HANDLER_H_ #define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TRACING_HANDLER_H_ +#include "base/debug/trace_event.h" #include "content/browser/devtools/devtools_protocol.h" #include "content/public/browser/trace_subscriber.h" @@ -34,6 +35,9 @@ class DevToolsTracingHandler scoped_ptr<DevToolsProtocol::Response> OnEnd( DevToolsProtocol::Command* command); + base::debug::TraceLog::Options TraceOptionsFromString( + const std::string& options); + bool is_running_; DISALLOW_COPY_AND_ASSIGN(DevToolsTracingHandler); diff --git a/content/browser/tracing/trace_controller_impl.cc b/content/browser/tracing/trace_controller_impl.cc index e0aed6e..e416126 100644 --- a/content/browser/tracing/trace_controller_impl.cc +++ b/content/browser/tracing/trace_controller_impl.cc @@ -113,7 +113,8 @@ bool TraceControllerImpl::GetKnownCategoriesAsync(TraceSubscriber* subscriber) { // message. So to get known categories, just begin and end tracing immediately // afterwards. This will ping all the child processes for categories. is_get_categories_ = true; - bool success = BeginTracing(subscriber, "*") && + bool success = BeginTracing(subscriber, "*", + TraceLog::GetInstance()->trace_options()) && EndTracingAsync(subscriber); is_get_categories_ = success; return success; @@ -122,28 +123,31 @@ bool TraceControllerImpl::GetKnownCategoriesAsync(TraceSubscriber* subscriber) { bool TraceControllerImpl::BeginTracing( TraceSubscriber* subscriber, const std::vector<std::string>& included_categories, - const std::vector<std::string>& excluded_categories) { + const std::vector<std::string>& excluded_categories, + base::debug::TraceLog::Options options) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); if (!can_begin_tracing(subscriber)) return false; // Enable tracing - TraceLog::GetInstance()->SetEnabled(included_categories, excluded_categories); + TraceLog::GetInstance()->SetEnabled(included_categories, excluded_categories, + options); OnTracingBegan(subscriber); return true; } bool TraceControllerImpl::BeginTracing(TraceSubscriber* subscriber, - const std::string& categories) { + const std::string& categories, + base::debug::TraceLog::Options options) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); if (!can_begin_tracing(subscriber)) return false; // Enable tracing - TraceLog::GetInstance()->SetEnabled(categories); + TraceLog::GetInstance()->SetEnabled(categories, options); OnTracingBegan(subscriber); @@ -261,7 +265,8 @@ void TraceControllerImpl::AddFilter(TraceMessageFilter* filter) { filters_.insert(filter); if (is_tracing_enabled()) { - filter->SendBeginTracing(included_categories_, excluded_categories_); + filter->SendBeginTracing(included_categories_, excluded_categories_, + trace_options_); if (!watch_category_.empty()) filter->SendSetWatchEvent(watch_category_, watch_name_); } @@ -285,9 +290,12 @@ void TraceControllerImpl::OnTracingBegan(TraceSubscriber* subscriber) { TraceLog::GetInstance()->GetEnabledTraceCategories(&included_categories_, &excluded_categories_); + trace_options_ = TraceLog::GetInstance()->trace_options(); + // Notify all child processes. for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { - it->get()->SendBeginTracing(included_categories_, excluded_categories_); + it->get()->SendBeginTracing(included_categories_, excluded_categories_, + trace_options_); } } diff --git a/content/browser/tracing/trace_controller_impl.h b/content/browser/tracing/trace_controller_impl.h index 501f561..165965d 100644 --- a/content/browser/tracing/trace_controller_impl.h +++ b/content/browser/tracing/trace_controller_impl.h @@ -38,11 +38,13 @@ class TraceControllerImpl : public TraceController { // Else if excluded_categories is non-empty, everything but those are traced. bool BeginTracing(TraceSubscriber* subscriber, const std::vector<std::string>& included_categories, - const std::vector<std::string>& excluded_categories); + const std::vector<std::string>& excluded_categories, + base::debug::TraceLog::Options options); // TraceController implementation: virtual bool BeginTracing(TraceSubscriber* subscriber, - const std::string& categories) OVERRIDE; + const std::string& categories, + base::debug::TraceLog::Options options) OVERRIDE; virtual bool EndTracingAsync(TraceSubscriber* subscriber) OVERRIDE; virtual bool GetTraceBufferPercentFullAsync( TraceSubscriber* subscriber) OVERRIDE; @@ -106,6 +108,7 @@ class TraceControllerImpl : public TraceController { std::vector<std::string> excluded_categories_; std::string watch_category_; std::string watch_name_; + base::debug::TraceLog::Options trace_options_; DISALLOW_COPY_AND_ASSIGN(TraceControllerImpl); }; diff --git a/content/browser/tracing/trace_message_filter.cc b/content/browser/tracing/trace_message_filter.cc index de5b2fd..8894cff 100644 --- a/content/browser/tracing/trace_message_filter.cc +++ b/content/browser/tracing/trace_message_filter.cc @@ -56,11 +56,12 @@ bool TraceMessageFilter::OnMessageReceived(const IPC::Message& message, void TraceMessageFilter::SendBeginTracing( const std::vector<std::string>& included_categories, - const std::vector<std::string>& excluded_categories) { + const std::vector<std::string>& excluded_categories, + base::debug::TraceLog::Options options) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - Send(new TracingMsg_BeginTracing(included_categories, - excluded_categories, - base::TimeTicks::NowFromSystemTraceTime())); + Send(new TracingMsg_BeginTracing(included_categories, excluded_categories, + base::TimeTicks::NowFromSystemTraceTime(), + options)); } void TraceMessageFilter::SendEndTracing() { diff --git a/content/browser/tracing/trace_message_filter.h b/content/browser/tracing/trace_message_filter.h index ae6d571..aa5f336 100644 --- a/content/browser/tracing/trace_message_filter.h +++ b/content/browser/tracing/trace_message_filter.h @@ -8,6 +8,7 @@ #include <string> #include <vector> +#include "base/debug/trace_event.h" #include "content/public/browser/browser_message_filter.h" namespace content { @@ -28,7 +29,8 @@ class TraceMessageFilter : public BrowserMessageFilter { bool* message_was_ok) OVERRIDE; void SendBeginTracing(const std::vector<std::string>& included_categories, - const std::vector<std::string>& excluded_categories); + const std::vector<std::string>& excluded_categories, + base::debug::TraceLog::Options options); void SendEndTracing(); void SendGetTraceBufferPercentFull(); void SendSetWatchEvent(const std::string& category_name, diff --git a/content/browser/tracing/tracing_ui.cc b/content/browser/tracing/tracing_ui.cc index 72f6451..33547fe 100644 --- a/content/browser/tracing/tracing_ui.cc +++ b/content/browser/tracing/tracing_ui.cc @@ -372,7 +372,8 @@ void TracingMessageHandler::SaveTraceFileComplete() { void TracingMessageHandler::OnBeginTracing(const base::ListValue* args) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK_EQ(args->GetSize(), (size_t) 2); + DCHECK_GE(args->GetSize(), (size_t) 2); + DCHECK_LE(args->GetSize(), (size_t) 3); bool system_tracing_requested = false; bool ok = args->GetBoolean(0, &system_tracing_requested); @@ -382,12 +383,22 @@ void TracingMessageHandler::OnBeginTracing(const base::ListValue* args) { ok = args->GetString(1, &chrome_categories); DCHECK(ok); + base::debug::TraceLog::Options options = + base::debug::TraceLog::RECORD_UNTIL_FULL; + if (args->GetSize() >= 3) { + std::string options_; + ok = args->GetString(2, &options_); + DCHECK(ok); + options = base::debug::TraceLog::TraceOptionsFromString(options_); + } + trace_enabled_ = true; // TODO(jbates) This may fail, but that's OK for current use cases. // Ex: Multiple about:gpu traces can not trace simultaneously. // TODO(nduca) send feedback to javascript about whether or not BeginTracing // was successful. - TraceController::GetInstance()->BeginTracing(this, chrome_categories); + TraceController::GetInstance()->BeginTracing(this, chrome_categories, + options); if (system_tracing_requested) { #if defined(OS_CHROMEOS) diff --git a/content/public/browser/trace_controller.h b/content/public/browser/trace_controller.h index 6bdff6c..211f7f5 100644 --- a/content/public/browser/trace_controller.h +++ b/content/public/browser/trace_controller.h @@ -5,6 +5,7 @@ #ifndef CONTENT_PUBLIC_BROWSER_TRACE_CONTROLLER_H_ #define CONTENT_PUBLIC_BROWSER_TRACE_CONTROLLER_H_ +#include "base/debug/trace_event.h" #include "content/common/content_export.h" namespace content { @@ -35,11 +36,14 @@ class TraceController { // All the same rules apply above, so for example, having both included and // excluded categories in the same list would not be supported. // + // |mode| is the tracing mode being used. + // // Example: BeginTracing("test_MyTest*"); // Example: BeginTracing("test_MyTest*,test_OtherStuff"); // Example: BeginTracing("-excluded_category1,-excluded_category2"); virtual bool BeginTracing(TraceSubscriber* subscriber, - const std::string& categories) = 0; + const std::string& categories, + base::debug::TraceLog::Options options) = 0; // Called by browser process to stop tracing events on all processes. // |