diff options
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. // |