diff options
author | rubentopo@gmail.com <rubentopo@gmail.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-19 08:49:03 +0000 |
---|---|---|
committer | rubentopo@gmail.com <rubentopo@gmail.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-19 08:49:03 +0000 |
commit | d936677a24d0a18fc35935a999b066496f9a6ec7 (patch) | |
tree | 8943336492769d04e1cbe806b49912d32f485b8a /base | |
parent | df9416c847ceefdb4d1749cfd53866775f9a6535 (diff) | |
download | chromium_src-d936677a24d0a18fc35935a999b066496f9a6ec7.zip chromium_src-d936677a24d0a18fc35935a999b066496f9a6ec7.tar.gz chromium_src-d936677a24d0a18fc35935a999b066496f9a6ec7.tar.bz2 |
Category group support/Renamings.
Related review:
https://codereview.chromium.org/11823016/
BUG=168284
TEST=TraceEventTestFixture.Categories, TraceEventTestFixture.CategoryFilter
R=nduca
Review URL: https://chromiumcodereview.appspot.com/12150004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195109 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/debug/trace_event.h | 476 | ||||
-rw-r--r-- | base/debug/trace_event_android.cc | 24 | ||||
-rw-r--r-- | base/debug/trace_event_impl.cc | 433 | ||||
-rw-r--r-- | base/debug/trace_event_impl.h | 149 | ||||
-rw-r--r-- | base/debug/trace_event_unittest.cc | 263 | ||||
-rw-r--r-- | base/test/trace_event_analyzer_unittest.cc | 6 |
6 files changed, 808 insertions, 543 deletions
diff --git a/base/debug/trace_event.h b/base/debug/trace_event.h index 838b2a6d..cdfe9e3 100644 --- a/base/debug/trace_event.h +++ b/base/debug/trace_event.h @@ -19,6 +19,15 @@ // implicitly with a string. For example: // TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent") // +// It is often the case that one trace may belong in multiple categories at the +// same time. The first argument to the trace can be a comma-separated list of +// categories, forming a category group, like: +// +// TRACE_EVENT_INSTANT0("input,views", "OnMouseOver") +// +// We can enable/disable tracing of OnMouseOver by enabling/disabling either +// category. +// // Events can be INSTANT, or can be pairs of BEGIN and END in the same scope: // TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly") // doSomethingCostly() @@ -99,9 +108,9 @@ // // Memory scoping note: // Tracing copies the pointers, not the string content, of the strings passed -// in for category, name, and arg_names. Thus, the following code will +// in for category_group, name, and arg_names. Thus, the following code will // cause problems: -// char* str = strdup("impprtantName"); +// char* str = strdup("importantName"); // TRACE_EVENT_INSTANT0("SUBSYSTEM", str); // BAD! // free(str); // Trace system now has dangling pointer // @@ -164,7 +173,7 @@ // the static variable is safe, as they will be serialized by the lock and // multiple calls will return the same pointer to the category. // -// Then the category_enabled flag is checked. This is a unsigned char, and +// Then the category_group_enabled flag is checked. This is a unsigned char, and // not intended to be multithread safe. It optimizes access to AddTraceEvent // which is threadsafe internally via TraceLog::lock_. The enabled flag may // cause some threads to incorrectly call or skip calling AddTraceEvent near @@ -201,43 +210,45 @@ // enabled, then this does nothing. // - category and name strings must have application lifetime (statics or // literals). They may not include " chars. -#define TRACE_EVENT0(category, name) \ - INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name) -#define TRACE_EVENT1(category, name, arg1_name, arg1_val) \ - INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val) -#define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ - INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val, \ +#define TRACE_EVENT0(category_group, name) \ + INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name) +#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \ + INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val) +#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, \ + arg2_val) \ + INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val, \ arg2_name, arg2_val) // Same as TRACE_EVENT except that they are not included in official builds. #ifdef OFFICIAL_BUILD -#define UNSHIPPED_TRACE_EVENT0(category, name) (void)0 -#define UNSHIPPED_TRACE_EVENT1(category, name, arg1_name, arg1_val) (void)0 -#define UNSHIPPED_TRACE_EVENT2(category, name, arg1_name, arg1_val, \ +#define UNSHIPPED_TRACE_EVENT0(category_group, name) (void)0 +#define UNSHIPPED_TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \ + (void)0 +#define UNSHIPPED_TRACE_EVENT2(category_group, name, arg1_name, arg1_val, \ arg2_name, arg2_val) (void)0 -#define UNSHIPPED_TRACE_EVENT_INSTANT0(category, name, scope) (void)0 -#define UNSHIPPED_TRACE_EVENT_INSTANT1(category, name, scope, \ +#define UNSHIPPED_TRACE_EVENT_INSTANT0(category_group, name, scope) (void)0 +#define UNSHIPPED_TRACE_EVENT_INSTANT1(category_group, name, scope, \ arg1_name, arg1_val) (void)0 -#define UNSHIPPED_TRACE_EVENT_INSTANT2(category, name, scope, \ +#define UNSHIPPED_TRACE_EVENT_INSTANT2(category_group, name, scope, \ arg1_name, arg1_val, \ arg2_name, arg2_val) (void)0 #else -#define UNSHIPPED_TRACE_EVENT0(category, name) \ - TRACE_EVENT0(category, name) -#define UNSHIPPED_TRACE_EVENT1(category, name, arg1_name, arg1_val) \ - TRACE_EVENT1(category, name, arg1_name, arg1_val) -#define UNSHIPPED_TRACE_EVENT2(category, name, arg1_name, arg1_val, \ +#define UNSHIPPED_TRACE_EVENT0(category_group, name) \ + TRACE_EVENT0(category_group, name) +#define UNSHIPPED_TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \ + TRACE_EVENT1(category_group, name, arg1_name, arg1_val) +#define UNSHIPPED_TRACE_EVENT2(category_group, name, arg1_name, arg1_val, \ arg2_name, arg2_val) \ - TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) -#define UNSHIPPED_TRACE_EVENT_INSTANT0(category, name, scope) \ - TRACE_EVENT_INSTANT0(category, name, scope) -#define UNSHIPPED_TRACE_EVENT_INSTANT1(category, name, scope, \ + TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val) +#define UNSHIPPED_TRACE_EVENT_INSTANT0(category_group, name, scope) \ + TRACE_EVENT_INSTANT0(category_group, name, scope) +#define UNSHIPPED_TRACE_EVENT_INSTANT1(category_group, name, scope, \ arg1_name, arg1_val) \ - TRACE_EVENT_INSTANT1(category, name, scope, arg1_name, arg1_val) -#define UNSHIPPED_TRACE_EVENT_INSTANT2(category, name, scope, \ + TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) +#define UNSHIPPED_TRACE_EVENT_INSTANT2(category_group, name, scope, \ arg1_name, arg1_val, \ arg2_name, arg2_val) \ - TRACE_EVENT_INSTANT2(category, name, scope, arg1_name, arg1_val, \ + TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \ arg2_name, arg2_val) #endif @@ -246,30 +257,31 @@ // does nothing. // - category and name strings must have application lifetime (statics or // literals). They may not include " chars. -#define TRACE_EVENT_INSTANT0(category, name, scope) \ +#define TRACE_EVENT_INSTANT0(category_group, name, scope) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ - category, name, TRACE_EVENT_FLAG_NONE | scope) -#define TRACE_EVENT_INSTANT1(category, name, scope, arg1_name, arg1_val) \ + category_group, name, TRACE_EVENT_FLAG_NONE | scope) +#define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ - category, name, TRACE_EVENT_FLAG_NONE | scope, \ + category_group, name, TRACE_EVENT_FLAG_NONE | scope, \ arg1_name, arg1_val) -#define TRACE_EVENT_INSTANT2(category, name, scope, arg1_name, arg1_val, \ +#define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \ arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ - category, name, TRACE_EVENT_FLAG_NONE | scope, \ + category_group, name, TRACE_EVENT_FLAG_NONE | scope, \ arg1_name, arg1_val, arg2_name, arg2_val) -#define TRACE_EVENT_COPY_INSTANT0(category, name, scope) \ +#define TRACE_EVENT_COPY_INSTANT0(category_group, name, scope) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ - category, name, TRACE_EVENT_FLAG_COPY | scope) -#define TRACE_EVENT_COPY_INSTANT1(category, name, scope, \ + category_group, name, TRACE_EVENT_FLAG_COPY | scope) +#define TRACE_EVENT_COPY_INSTANT1(category_group, name, scope, \ arg1_name, arg1_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ - category, name, TRACE_EVENT_FLAG_COPY | scope, arg1_name, arg1_val) -#define TRACE_EVENT_COPY_INSTANT2(category, name, scope, \ + category_group, name, TRACE_EVENT_FLAG_COPY | scope, arg1_name, \ + arg1_val) +#define TRACE_EVENT_COPY_INSTANT2(category_group, name, scope, \ arg1_name, arg1_val, \ arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ - category, name, TRACE_EVENT_FLAG_COPY | scope, \ + category_group, name, TRACE_EVENT_FLAG_COPY | scope, \ arg1_name, arg1_val, arg2_name, arg2_val) // Sets the current sample state to the given category and name (both must be @@ -288,101 +300,101 @@ // does nothing. // - category and name strings must have application lifetime (statics or // literals). They may not include " chars. -#define TRACE_EVENT_BEGIN0(category, name) \ +#define TRACE_EVENT_BEGIN0(category_group, name) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ - category, name, TRACE_EVENT_FLAG_NONE) -#define TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) \ + category_group, name, TRACE_EVENT_FLAG_NONE) +#define TRACE_EVENT_BEGIN1(category_group, name, arg1_name, arg1_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ - category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) -#define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \ + category_group, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) +#define TRACE_EVENT_BEGIN2(category_group, name, arg1_name, arg1_val, \ arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ - category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ + category_group, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ arg2_name, arg2_val) -#define TRACE_EVENT_COPY_BEGIN0(category, name) \ +#define TRACE_EVENT_COPY_BEGIN0(category_group, name) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ - category, name, TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) \ + category_group, name, TRACE_EVENT_FLAG_COPY) +#define TRACE_EVENT_COPY_BEGIN1(category_group, name, arg1_name, arg1_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ - category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) -#define TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \ + category_group, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) +#define TRACE_EVENT_COPY_BEGIN2(category_group, name, arg1_name, arg1_val, \ arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ - category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ + category_group, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ arg2_name, arg2_val) // Similar to TRACE_EVENT_BEGINx but with a custom |at| timestamp provided. // - |id| is used to match the _BEGIN event with the _END event. -// Events are considered to match if their category, name and id values all -// match. |id| must either be a pointer or an integer value up to 64 bits. If -// it's a pointer, the bits will be xored with a hash of the process ID so +// Events are considered to match if their category_group, name and id values +// all match. |id| must either be a pointer or an integer value up to 64 bits. +// If it's a pointer, the bits will be xored with a hash of the process ID so // that the same pointer on two different processes will not collide. -#define TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(category, \ +#define TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(category_group, \ name, id, thread_id, timestamp) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ - TRACE_EVENT_PHASE_ASYNC_BEGIN, category, name, id, thread_id, \ + TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \ timestamp, TRACE_EVENT_FLAG_NONE) #define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0( \ - category, name, id, thread_id, timestamp) \ + category_group, name, id, thread_id, timestamp) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ - TRACE_EVENT_PHASE_ASYNC_BEGIN, category, name, id, thread_id, \ + TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \ timestamp, TRACE_EVENT_FLAG_COPY) // Records a single END event for "name" immediately. If the category // is not enabled, then this does nothing. // - category and name strings must have application lifetime (statics or // literals). They may not include " chars. -#define TRACE_EVENT_END0(category, name) \ +#define TRACE_EVENT_END0(category_group, name) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ - category, name, TRACE_EVENT_FLAG_NONE) -#define TRACE_EVENT_END1(category, name, arg1_name, arg1_val) \ + category_group, name, TRACE_EVENT_FLAG_NONE) +#define TRACE_EVENT_END1(category_group, name, arg1_name, arg1_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ - category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) -#define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \ + category_group, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) +#define TRACE_EVENT_END2(category_group, name, arg1_name, arg1_val, \ arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ - category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ + category_group, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ arg2_name, arg2_val) -#define TRACE_EVENT_COPY_END0(category, name) \ +#define TRACE_EVENT_COPY_END0(category_group, name) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ - category, name, TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) \ + category_group, name, TRACE_EVENT_FLAG_COPY) +#define TRACE_EVENT_COPY_END1(category_group, name, arg1_name, arg1_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ - category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) -#define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \ + category_group, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) +#define TRACE_EVENT_COPY_END2(category_group, name, arg1_name, arg1_val, \ arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ - category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ + category_group, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ arg2_name, arg2_val) // Similar to TRACE_EVENT_ENDx but with a custom |at| timestamp provided. // - |id| is used to match the _BEGIN event with the _END event. -// Events are considered to match if their category, name and id values all -// match. |id| must either be a pointer or an integer value up to 64 bits. If -// it's a pointer, the bits will be xored with a hash of the process ID so +// Events are considered to match if their category_group, name and id values +// all match. |id| must either be a pointer or an integer value up to 64 bits. +// If it's a pointer, the bits will be xored with a hash of the process ID so // that the same pointer on two different processes will not collide. -#define TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0(category, \ +#define TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0(category_group, \ name, id, thread_id, timestamp) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ - TRACE_EVENT_PHASE_ASYNC_END, category, name, id, thread_id, timestamp, \ - TRACE_EVENT_FLAG_NONE) + TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id, \ + timestamp, TRACE_EVENT_FLAG_NONE) #define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0( \ - category, name, id, thread_id, timestamp) \ + category_group, name, id, thread_id, timestamp) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ - TRACE_EVENT_PHASE_ASYNC_END, category, name, id, thread_id, timestamp, \ - TRACE_EVENT_FLAG_COPY) + TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id, \ + timestamp, TRACE_EVENT_FLAG_COPY) // Records the value of a counter called "name" immediately. Value // must be representable as a 32 bit integer. // - category and name strings must have application lifetime (statics or // literals). They may not include " chars. -#define TRACE_COUNTER1(category, name, value) \ +#define TRACE_COUNTER1(category_group, name, value) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ - category, name, TRACE_EVENT_FLAG_NONE, \ + category_group, name, TRACE_EVENT_FLAG_NONE, \ "value", static_cast<int>(value)) -#define TRACE_COPY_COUNTER1(category, name, value) \ +#define TRACE_COPY_COUNTER1(category_group, name, value) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ - category, name, TRACE_EVENT_FLAG_COPY, \ + category_group, name, TRACE_EVENT_FLAG_COPY, \ "value", static_cast<int>(value)) // Records the values of a multi-parted counter called "name" immediately. @@ -390,16 +402,16 @@ // values as a stacked-bar chart. // - category and name strings must have application lifetime (statics or // literals). They may not include " chars. -#define TRACE_COUNTER2(category, name, value1_name, value1_val, \ +#define TRACE_COUNTER2(category_group, name, value1_name, value1_val, \ value2_name, value2_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ - category, name, TRACE_EVENT_FLAG_NONE, \ + category_group, name, TRACE_EVENT_FLAG_NONE, \ value1_name, static_cast<int>(value1_val), \ value2_name, static_cast<int>(value2_val)) -#define TRACE_COPY_COUNTER2(category, name, value1_name, value1_val, \ +#define TRACE_COPY_COUNTER2(category_group, name, value1_name, value1_val, \ value2_name, value2_val) \ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ - category, name, TRACE_EVENT_FLAG_COPY, \ + category_group, name, TRACE_EVENT_FLAG_COPY, \ value1_name, static_cast<int>(value1_val), \ value2_name, static_cast<int>(value2_val)) @@ -411,13 +423,13 @@ // be a pointer or an integer value up to 64 bits. If it's a pointer, the bits // will be xored with a hash of the process ID so that the same pointer on // two different processes will not collide. -#define TRACE_COUNTER_ID1(category, name, id, value) \ +#define TRACE_COUNTER_ID1(category_group, name, id, value) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ - category, name, id, TRACE_EVENT_FLAG_NONE, \ + category_group, name, id, TRACE_EVENT_FLAG_NONE, \ "value", static_cast<int>(value)) -#define TRACE_COPY_COUNTER_ID1(category, name, id, value) \ +#define TRACE_COPY_COUNTER_ID1(category_group, name, id, value) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ - category, name, id, TRACE_EVENT_FLAG_COPY, \ + category_group, name, id, TRACE_EVENT_FLAG_COPY, \ "value", static_cast<int>(value)) // Records the values of a multi-parted counter called "name" immediately. @@ -429,16 +441,16 @@ // be a pointer or an integer value up to 64 bits. If it's a pointer, the bits // will be xored with a hash of the process ID so that the same pointer on // two different processes will not collide. -#define TRACE_COUNTER_ID2(category, name, id, value1_name, value1_val, \ +#define TRACE_COUNTER_ID2(category_group, name, id, value1_name, value1_val, \ value2_name, value2_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ - category, name, id, TRACE_EVENT_FLAG_NONE, \ + category_group, name, id, TRACE_EVENT_FLAG_NONE, \ value1_name, static_cast<int>(value1_val), \ value2_name, static_cast<int>(value2_val)) -#define TRACE_COPY_COUNTER_ID2(category, name, id, value1_name, value1_val, \ - value2_name, value2_val) \ +#define TRACE_COPY_COUNTER_ID2(category_group, name, id, value1_name, \ + value1_val, value2_name, value2_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ - category, name, id, TRACE_EVENT_FLAG_COPY, \ + category_group, name, id, TRACE_EVENT_FLAG_COPY, \ value1_name, static_cast<int>(value1_val), \ value2_name, static_cast<int>(value2_val)) @@ -449,9 +461,9 @@ // - category and name strings must have application lifetime (statics or // literals). They may not include " chars. // - |id| is used to match the ASYNC_BEGIN event with the ASYNC_END event. ASYNC -// events are considered to match if their category, name and id values all -// match. |id| must either be a pointer or an integer value up to 64 bits. If -// it's a pointer, the bits will be xored with a hash of the process ID so +// events are considered to match if their category_group, name and id values +// all match. |id| must either be a pointer or an integer value up to 64 bits. +// If it's a pointer, the bits will be xored with a hash of the process ID so // that the same pointer on two different processes will not collide. // An asynchronous operation can consist of multiple phases. The first phase is // defined by the ASYNC_BEGIN calls. Additional phases can be defined using the @@ -460,28 +472,30 @@ // drawn on the thread defined in the ASYNC_BEGIN event), but all events in that // operation must use the same |name| and |id|. Each event can have its own // args. -#define TRACE_EVENT_ASYNC_BEGIN0(category, name, id) \ +#define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ - category, name, id, TRACE_EVENT_FLAG_NONE) -#define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \ + category_group, name, id, TRACE_EVENT_FLAG_NONE) +#define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, \ + arg1_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ - category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) -#define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \ - arg2_name, arg2_val) \ + category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) +#define TRACE_EVENT_ASYNC_BEGIN2(category_group, name, id, arg1_name, \ + arg1_val, arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ - category, name, id, TRACE_EVENT_FLAG_NONE, \ + category_group, name, id, TRACE_EVENT_FLAG_NONE, \ arg1_name, arg1_val, arg2_name, arg2_val) -#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category, name, id) \ +#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category_group, name, id) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ - category, name, id, TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \ + category_group, name, id, TRACE_EVENT_FLAG_COPY) +#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category_group, name, id, arg1_name, \ + arg1_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ - category, name, id, TRACE_EVENT_FLAG_COPY, \ + category_group, name, id, TRACE_EVENT_FLAG_COPY, \ arg1_name, arg1_val) -#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \ - arg2_name, arg2_val) \ +#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category_group, name, id, arg1_name, \ + arg1_val, arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ - category, name, id, TRACE_EVENT_FLAG_COPY, \ + category_group, name, id, TRACE_EVENT_FLAG_COPY, \ arg1_name, arg1_val, arg2_name, arg2_val) // Records a single ASYNC_STEP event for |step| immediately. If the category @@ -489,47 +503,48 @@ // ASYNC_BEGIN event above. The |step| param identifies this step within the // async event. This should be called at the beginning of the next phase of an // asynchronous operation. -#define TRACE_EVENT_ASYNC_STEP0(category, name, id, step) \ +#define TRACE_EVENT_ASYNC_STEP0(category_group, name, id, step) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ - category, name, id, TRACE_EVENT_FLAG_NONE, "step", step) -#define TRACE_EVENT_ASYNC_STEP1(category, name, id, step, \ + category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step) +#define TRACE_EVENT_ASYNC_STEP1(category_group, name, id, step, \ arg1_name, arg1_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ - category, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \ + category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \ arg1_name, arg1_val) -#define TRACE_EVENT_COPY_ASYNC_STEP0(category, name, id, step) \ +#define TRACE_EVENT_COPY_ASYNC_STEP0(category_group, name, id, step) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ - category, name, id, TRACE_EVENT_FLAG_COPY, "step", step) -#define TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step, \ + category_group, name, id, TRACE_EVENT_FLAG_COPY, "step", step) +#define TRACE_EVENT_COPY_ASYNC_STEP1(category_group, name, id, step, \ arg1_name, arg1_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ - category, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \ + category_group, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \ arg1_name, arg1_val) // Records a single ASYNC_END event for "name" immediately. If the category // is not enabled, then this does nothing. -#define TRACE_EVENT_ASYNC_END0(category, name, id) \ +#define TRACE_EVENT_ASYNC_END0(category_group, name, id) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ - category, name, id, TRACE_EVENT_FLAG_NONE) -#define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \ + category_group, name, id, TRACE_EVENT_FLAG_NONE) +#define TRACE_EVENT_ASYNC_END1(category_group, name, id, arg1_name, arg1_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ - category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) -#define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, \ + category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) +#define TRACE_EVENT_ASYNC_END2(category_group, name, id, arg1_name, arg1_val, \ arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ - category, name, id, TRACE_EVENT_FLAG_NONE, \ + category_group, name, id, TRACE_EVENT_FLAG_NONE, \ arg1_name, arg1_val, arg2_name, arg2_val) -#define TRACE_EVENT_COPY_ASYNC_END0(category, name, id) \ +#define TRACE_EVENT_COPY_ASYNC_END0(category_group, name, id) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ - category, name, id, TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_ASYNC_END1(category, name, id, arg1_name, arg1_val) \ + category_group, name, id, TRACE_EVENT_FLAG_COPY) +#define TRACE_EVENT_COPY_ASYNC_END1(category_group, name, id, arg1_name, \ + arg1_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ - category, name, id, TRACE_EVENT_FLAG_COPY, \ + category_group, name, id, TRACE_EVENT_FLAG_COPY, \ arg1_name, arg1_val) -#define TRACE_EVENT_COPY_ASYNC_END2(category, name, id, arg1_name, arg1_val, \ - arg2_name, arg2_val) \ +#define TRACE_EVENT_COPY_ASYNC_END2(category_group, name, id, arg1_name, \ + arg1_val, arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ - category, name, id, TRACE_EVENT_FLAG_COPY, \ + category_group, name, id, TRACE_EVENT_FLAG_COPY, \ arg1_name, arg1_val, arg2_name, arg2_val) @@ -539,9 +554,9 @@ // - category and name strings must have application lifetime (statics or // literals). They may not include " chars. // - |id| is used to match the FLOW_BEGIN event with the FLOW_END event. FLOW -// events are considered to match if their category, name and id values all -// match. |id| must either be a pointer or an integer value up to 64 bits. If -// it's a pointer, the bits will be xored with a hash of the process ID so +// events are considered to match if their category_group, name and id values +// all match. |id| must either be a pointer or an integer value up to 64 bits. +// If it's a pointer, the bits will be xored with a hash of the process ID so // that the same pointer on two different processes will not collide. // FLOW events are different from ASYNC events in how they are drawn by the // tracing UI. A FLOW defines asynchronous data flow, such as posting a task @@ -552,28 +567,29 @@ // macros. When the operation completes, call FLOW_END. An async operation can // span threads and processes, but all events in that operation must use the // same |name| and |id|. Each event can have its own args. -#define TRACE_EVENT_FLOW_BEGIN0(category, name, id) \ +#define TRACE_EVENT_FLOW_BEGIN0(category_group, name, id) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ - category, name, id, TRACE_EVENT_FLAG_NONE) -#define TRACE_EVENT_FLOW_BEGIN1(category, name, id, arg1_name, arg1_val) \ + category_group, name, id, TRACE_EVENT_FLAG_NONE) +#define TRACE_EVENT_FLOW_BEGIN1(category_group, name, id, arg1_name, arg1_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ - category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) -#define TRACE_EVENT_FLOW_BEGIN2(category, name, id, arg1_name, arg1_val, \ + category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) +#define TRACE_EVENT_FLOW_BEGIN2(category_group, name, id, arg1_name, arg1_val, \ arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ - category, name, id, TRACE_EVENT_FLAG_NONE, \ + category_group, name, id, TRACE_EVENT_FLAG_NONE, \ arg1_name, arg1_val, arg2_name, arg2_val) -#define TRACE_EVENT_COPY_FLOW_BEGIN0(category, name, id) \ +#define TRACE_EVENT_COPY_FLOW_BEGIN0(category_group, name, id) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ - category, name, id, TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_FLOW_BEGIN1(category, name, id, arg1_name, arg1_val) \ + category_group, name, id, TRACE_EVENT_FLAG_COPY) +#define TRACE_EVENT_COPY_FLOW_BEGIN1(category_group, name, id, arg1_name, \ + arg1_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ - category, name, id, TRACE_EVENT_FLAG_COPY, \ + category_group, name, id, TRACE_EVENT_FLAG_COPY, \ arg1_name, arg1_val) -#define TRACE_EVENT_COPY_FLOW_BEGIN2(category, name, id, arg1_name, arg1_val, \ - arg2_name, arg2_val) \ +#define TRACE_EVENT_COPY_FLOW_BEGIN2(category_group, name, id, arg1_name, \ + arg1_val, arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ - category, name, id, TRACE_EVENT_FLAG_COPY, \ + category_group, name, id, TRACE_EVENT_FLAG_COPY, \ arg1_name, arg1_val, arg2_name, arg2_val) // Records a single FLOW_STEP event for |step| immediately. If the category @@ -581,80 +597,81 @@ // FLOW_BEGIN event above. The |step| param identifies this step within the // async event. This should be called at the beginning of the next phase of an // asynchronous operation. -#define TRACE_EVENT_FLOW_STEP0(category, name, id, step) \ +#define TRACE_EVENT_FLOW_STEP0(category_group, name, id, step) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \ - category, name, id, TRACE_EVENT_FLAG_NONE, "step", step) -#define TRACE_EVENT_FLOW_STEP1(category, name, id, step, \ + category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step) +#define TRACE_EVENT_FLOW_STEP1(category_group, name, id, step, \ arg1_name, arg1_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \ - category, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \ + category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \ arg1_name, arg1_val) -#define TRACE_EVENT_COPY_FLOW_STEP0(category, name, id, step) \ +#define TRACE_EVENT_COPY_FLOW_STEP0(category_group, name, id, step) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \ - category, name, id, TRACE_EVENT_FLAG_COPY, "step", step) -#define TRACE_EVENT_COPY_FLOW_STEP1(category, name, id, step, \ + category_group, name, id, TRACE_EVENT_FLAG_COPY, "step", step) +#define TRACE_EVENT_COPY_FLOW_STEP1(category_group, name, id, step, \ arg1_name, arg1_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \ - category, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \ + category_group, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \ arg1_name, arg1_val) // Records a single FLOW_END event for "name" immediately. If the category // is not enabled, then this does nothing. -#define TRACE_EVENT_FLOW_END0(category, name, id) \ +#define TRACE_EVENT_FLOW_END0(category_group, name, id) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \ - category, name, id, TRACE_EVENT_FLAG_NONE) -#define TRACE_EVENT_FLOW_END1(category, name, id, arg1_name, arg1_val) \ + category_group, name, id, TRACE_EVENT_FLAG_NONE) +#define TRACE_EVENT_FLOW_END1(category_group, name, id, arg1_name, arg1_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \ - category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) -#define TRACE_EVENT_FLOW_END2(category, name, id, arg1_name, arg1_val, \ + category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) +#define TRACE_EVENT_FLOW_END2(category_group, name, id, arg1_name, arg1_val, \ arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \ - category, name, id, TRACE_EVENT_FLAG_NONE, \ + category_group, name, id, TRACE_EVENT_FLAG_NONE, \ arg1_name, arg1_val, arg2_name, arg2_val) -#define TRACE_EVENT_COPY_FLOW_END0(category, name, id) \ +#define TRACE_EVENT_COPY_FLOW_END0(category_group, name, id) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \ - category, name, id, TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_FLOW_END1(category, name, id, arg1_name, arg1_val) \ + category_group, name, id, TRACE_EVENT_FLAG_COPY) +#define TRACE_EVENT_COPY_FLOW_END1(category_group, name, id, arg1_name, \ + arg1_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \ - category, name, id, TRACE_EVENT_FLAG_COPY, \ + category_group, name, id, TRACE_EVENT_FLAG_COPY, \ arg1_name, arg1_val) -#define TRACE_EVENT_COPY_FLOW_END2(category, name, id, arg1_name, arg1_val, \ - arg2_name, arg2_val) \ +#define TRACE_EVENT_COPY_FLOW_END2(category_group, name, id, arg1_name, \ + arg1_val, arg2_name, arg2_val) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \ - category, name, id, TRACE_EVENT_FLAG_COPY, \ + category_group, name, id, TRACE_EVENT_FLAG_COPY, \ arg1_name, arg1_val, arg2_name, arg2_val) // Macros to track the life time of arbitratry client objects. // See also TraceTrackableObject. -#define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category, name, id) \ +#define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_CREATE_OBJECT, \ - category, name, id, TRACE_EVENT_FLAG_NONE) + category_group, name, id, TRACE_EVENT_FLAG_NONE) -#define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category, name, id) \ +#define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) \ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_DELETE_OBJECT, \ - category, name, id, TRACE_EVENT_FLAG_NONE) + category_group, name, id, TRACE_EVENT_FLAG_NONE) //////////////////////////////////////////////////////////////////////////////// // Implementation specific tracing API definitions. // Get a pointer to the enabled state of the given trace category. Only -// long-lived literal strings should be given as the category name. The returned -// pointer can be held permanently in a local static for example. If the -// unsigned char is non-zero, tracing is enabled. If tracing is enabled, +// long-lived literal strings should be given as the category group. The +// returned pointer can be held permanently in a local static for example. If +// the unsigned char is non-zero, tracing is enabled. If tracing is enabled, // TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled // between the load of the tracing state and the call to // TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out // for best performance when tracing is disabled. // const unsigned char* -// TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name) -#define TRACE_EVENT_API_GET_CATEGORY_ENABLED \ - base::debug::TraceLog::GetCategoryEnabled +// TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(const char* category_group) +#define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \ + base::debug::TraceLog::GetCategoryGroupEnabled // Add a trace event to the platform tracing system. // void TRACE_EVENT_API_ADD_TRACE_EVENT( // char phase, -// const unsigned char* category_enabled, +// const unsigned char* category_group_enabled, // const char* name, // unsigned long long id, // int num_args, @@ -668,7 +685,7 @@ // Add a trace event to the platform tracing system. // void TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP( // char phase, -// const unsigned char* category_enabled, +// const unsigned char* category_group_enabled, // const char* name, // unsigned long long id, // int thread_id, @@ -713,14 +730,14 @@ TRACE_EVENT_API_CLASS_EXPORT extern TRACE_EVENT_API_ATOMIC_WORD g_trace_state2; // No barriers are needed, because this code is designed to operate safely // even when the unsigned char* points to garbage data (which may be the case // on processors without cache coherency). -#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category) \ +#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group) \ static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) = 0; \ const unsigned char* INTERNAL_TRACE_EVENT_UID(catstatic) = \ reinterpret_cast<const unsigned char*>(TRACE_EVENT_API_ATOMIC_LOAD( \ INTERNAL_TRACE_EVENT_UID(atomic))); \ if (!INTERNAL_TRACE_EVENT_UID(catstatic)) { \ INTERNAL_TRACE_EVENT_UID(catstatic) = \ - TRACE_EVENT_API_GET_CATEGORY_ENABLED(category); \ + TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); \ TRACE_EVENT_API_ATOMIC_STORE(INTERNAL_TRACE_EVENT_UID(atomic), \ reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>( \ INTERNAL_TRACE_EVENT_UID(catstatic))); \ @@ -728,9 +745,9 @@ TRACE_EVENT_API_CLASS_EXPORT extern TRACE_EVENT_API_ATOMIC_WORD g_trace_state2; // Implementation detail: internal macro to create static category and add // event if the category is enabled. -#define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...) \ +#define INTERNAL_TRACE_EVENT_ADD(phase, category_group, name, flags, ...) \ do { \ - INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ + INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \ trace_event_internal::AddTraceEvent( \ phase, INTERNAL_TRACE_EVENT_UID(catstatic), name, \ @@ -741,8 +758,8 @@ TRACE_EVENT_API_CLASS_EXPORT extern TRACE_EVENT_API_ATOMIC_WORD g_trace_state2; // Implementation detail: internal macro to create static category and add begin // event if the category is enabled. Also adds the end event when the scope // ends. -#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...) \ - INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ +#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...) \ + INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ trace_event_internal::TraceEndOnScopeClose \ INTERNAL_TRACE_EVENT_UID(profileScope); \ if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \ @@ -757,10 +774,10 @@ TRACE_EVENT_API_CLASS_EXPORT extern TRACE_EVENT_API_ATOMIC_WORD g_trace_state2; // Implementation detail: internal macro to create static category and add // event if the category is enabled. -#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags, \ - ...) \ +#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category_group, name, id, \ + flags, ...) \ do { \ - INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ + INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \ unsigned char trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \ trace_event_internal::TraceID trace_event_trace_id( \ @@ -774,10 +791,10 @@ TRACE_EVENT_API_CLASS_EXPORT extern TRACE_EVENT_API_ATOMIC_WORD g_trace_state2; // Implementation detail: internal macro to create static category and add // event if the category is enabled. -#define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(phase, category, \ - name, id, thread_id, timestamp, flags, ...) \ +#define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(phase, \ + category_group, name, id, thread_id, timestamp, flags, ...) \ do { \ - INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ + INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \ unsigned char trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \ trace_event_internal::TraceID trace_event_trace_id( \ @@ -997,7 +1014,7 @@ static inline void SetTraceValue(const std::string& arg, static inline void AddTraceEventWithThreadIdAndTimestamp( char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, int thread_id, @@ -1011,13 +1028,13 @@ static inline void AddTraceEventWithThreadIdAndTimestamp( convertable_values[0].reset(arg1_val.release()); TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( - phase, category_enabled, name, id, thread_id, timestamp, + phase, category_group_enabled, name, id, thread_id, timestamp, num_args, &arg1_name, arg_types, NULL, convertable_values, flags); } static inline void AddTraceEvent( char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, unsigned char flags, @@ -1025,14 +1042,14 @@ static inline void AddTraceEvent( scoped_ptr<base::debug::ConvertableToTraceFormat> arg1_val) { int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime(); - AddTraceEventWithThreadIdAndTimestamp(phase, category_enabled, name, id, + AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, name, id, thread_id, now, flags, arg1_name, arg1_val.Pass()); } static inline void AddTraceEventWithThreadIdAndTimestamp( char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, int thread_id, @@ -1050,13 +1067,13 @@ static inline void AddTraceEventWithThreadIdAndTimestamp( convertable_values[1].reset(arg2_val.release()); TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( - phase, category_enabled, name, id, thread_id, timestamp, + phase, category_group_enabled, name, id, thread_id, timestamp, num_args, &arg1_name, arg_types, NULL, convertable_values, flags); } static inline void AddTraceEvent( char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, unsigned char flags, @@ -1066,7 +1083,7 @@ static inline void AddTraceEvent( scoped_ptr<base::debug::ConvertableToTraceFormat> arg2_val) { int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime(); - AddTraceEventWithThreadIdAndTimestamp(phase, category_enabled, name, id, + AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, name, id, thread_id, now, flags, arg1_name, arg1_val.Pass(), arg2_name, arg2_val.Pass()); @@ -1074,32 +1091,32 @@ static inline void AddTraceEvent( static inline void AddTraceEventWithThreadIdAndTimestamp( char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, int thread_id, const base::TimeTicks& timestamp, unsigned char flags) { TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( - phase, category_enabled, name, id, thread_id, timestamp, + phase, category_group_enabled, name, id, thread_id, timestamp, kZeroNumArgs, NULL, NULL, NULL, NULL, flags); } static inline void AddTraceEvent(char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, unsigned char flags) { int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime(); - AddTraceEventWithThreadIdAndTimestamp(phase, category_enabled, name, id, + AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, name, id, thread_id, now, flags); } template<class ARG1_TYPE> static inline void AddTraceEventWithThreadIdAndTimestamp( char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, int thread_id, @@ -1112,13 +1129,13 @@ static inline void AddTraceEventWithThreadIdAndTimestamp( unsigned long long arg_values[1]; SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]); TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( - phase, category_enabled, name, id, thread_id, timestamp, + phase, category_group_enabled, name, id, thread_id, timestamp, num_args, &arg1_name, arg_types, arg_values, NULL, flags); } template<class ARG1_TYPE> static inline void AddTraceEvent(char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, unsigned char flags, @@ -1126,7 +1143,7 @@ static inline void AddTraceEvent(char phase, const ARG1_TYPE& arg1_val) { int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime(); - AddTraceEventWithThreadIdAndTimestamp(phase, category_enabled, name, id, + AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, name, id, thread_id, now, flags, arg1_name, arg1_val); } @@ -1134,7 +1151,7 @@ static inline void AddTraceEvent(char phase, template<class ARG1_TYPE, class ARG2_TYPE> static inline void AddTraceEventWithThreadIdAndTimestamp( char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, int thread_id, @@ -1151,13 +1168,13 @@ static inline void AddTraceEventWithThreadIdAndTimestamp( SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]); SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]); TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( - phase, category_enabled, name, id, thread_id, timestamp, + phase, category_group_enabled, name, id, thread_id, timestamp, num_args, arg_names, arg_types, arg_values, NULL, flags); } template<class ARG1_TYPE, class ARG2_TYPE> static inline void AddTraceEvent(char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, unsigned char flags, @@ -1167,7 +1184,7 @@ static inline void AddTraceEvent(char phase, const ARG2_TYPE& arg2_val) { int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime(); - AddTraceEventWithThreadIdAndTimestamp(phase, category_enabled, name, id, + AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, name, id, thread_id, now, flags, arg1_name, arg1_val, arg2_name, arg2_val); } @@ -1182,9 +1199,9 @@ class TRACE_EVENT_API_CLASS_EXPORT TraceEndOnScopeClose { AddEventIfEnabled(); } - void Initialize(const unsigned char* category_enabled, + void Initialize(const unsigned char* category_group_enabled, const char* name) { - data_.category_enabled = category_enabled; + data_.category_group_enabled = category_group_enabled; data_.name = name; p_data_ = &data_; } @@ -1193,10 +1210,10 @@ class TRACE_EVENT_API_CLASS_EXPORT TraceEndOnScopeClose { // Add the end event if the category is still enabled. void AddEventIfEnabled() { // Only called when p_data_ is non-null. - if (*p_data_->category_enabled) { + if (*p_data_->category_group_enabled) { TRACE_EVENT_API_ADD_TRACE_EVENT( TRACE_EVENT_PHASE_END, - p_data_->category_enabled, + p_data_->category_group_enabled, p_data_->name, kNoEventId, kZeroNumArgs, NULL, NULL, NULL, NULL, TRACE_EVENT_FLAG_NONE); @@ -1209,7 +1226,7 @@ class TRACE_EVENT_API_CLASS_EXPORT TraceEndOnScopeClose { // members of this class instead, compiler warnings occur about potential // uninitialized accesses. struct Data { - const unsigned char* category_enabled; + const unsigned char* category_group_enabled; const char* name; }; Data* p_data_; @@ -1223,13 +1240,13 @@ class TRACE_EVENT_API_CLASS_EXPORT ScopedTrace { ~ScopedTrace(); private: - const unsigned char* category_enabled_; + const unsigned char* category_group_enabled_; const char* name_; }; // A support macro for TRACE_EVENT_BINARY_EFFICIENTx #define INTERNAL_TRACE_EVENT_BINARY_EFFICIENT_ADD_SCOPED( \ - category, name, ...) \ + category_group, name, ...) \ static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) = 0; \ trace_event_internal::ScopedTrace \ INTERNAL_TRACE_EVENT_UID(profileScope)( \ @@ -1239,8 +1256,8 @@ class TRACE_EVENT_API_CLASS_EXPORT ScopedTrace { // slower to execute when tracing is off. It should generally only be // used with code that is seldom executed or conditionally executed // when debugging. -#define TRACE_EVENT_BINARY_EFFICIENT0(category, name) \ - INTERNAL_TRACE_EVENT_BINARY_EFFICIENT_ADD_SCOPED(category, name) +#define TRACE_EVENT_BINARY_EFFICIENT0(category_group, name) \ + INTERNAL_TRACE_EVENT_BINARY_EFFICIENT_ADD_SCOPED(category_group, name) } // namespace trace_event_internal @@ -1249,19 +1266,20 @@ namespace debug { template<typename IDType> class TraceScopedTrackableObject { public: - TraceScopedTrackableObject(const char* category, const char* name, IDType id) - : category_(category), + TraceScopedTrackableObject(const char* category_group, const char* name, + IDType id) + : category_group_(category_group), name_(name), id_(id) { - TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_, name_, id_); + TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group_, name_, id_); } ~TraceScopedTrackableObject() { - TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_, name_, id_); + TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group_, name_, id_); } private: - const char* category_; + const char* category_group_; const char* name_; IDType id_; diff --git a/base/debug/trace_event_android.cc b/base/debug/trace_event_android.cc index 70e377b..8cc5f3c 100644 --- a/base/debug/trace_event_android.cc +++ b/base/debug/trace_event_android.cc @@ -17,7 +17,7 @@ int g_atrace_fd = -1; const char* kATraceMarkerFile = "/sys/kernel/debug/tracing/trace_marker"; void WriteEvent(char phase, - const char* category, + const char* category_group, const char* name, unsigned long long id, int num_args, @@ -48,7 +48,7 @@ void WriteEvent(char phase, } out += '|'; - out += category; + out += category_group; write(g_atrace_fd, out.c_str(), out.size()); } @@ -75,7 +75,7 @@ void TraceLog::StopATrace() { } void TraceLog::SendToATrace(char phase, - const char* category, + const char* category_group, const char* name, unsigned long long id, int num_args, @@ -88,20 +88,20 @@ void TraceLog::SendToATrace(char phase, switch (phase) { case TRACE_EVENT_PHASE_BEGIN: - WriteEvent('B', category, name, id, + WriteEvent('B', category_group, name, id, num_args, arg_names, arg_types, arg_values, flags); break; case TRACE_EVENT_PHASE_END: - // Though a single 'E' is enough, here append pid, name and category etc. - // so that unpaired events can be found easily. - WriteEvent('E', category, name, id, + // Though a single 'E' is enough, here append pid, name and + // category_group etc. So that unpaired events can be found easily. + WriteEvent('E', category_group, name, id, num_args, arg_names, arg_types, arg_values, flags); break; case TRACE_EVENT_PHASE_INSTANT: // Simulate an instance event with a pair of begin/end events. - WriteEvent('B', category, name, id, + WriteEvent('B', category_group, name, id, num_args, arg_names, arg_types, arg_values, flags); write(g_atrace_fd, "E", 1); break; @@ -114,7 +114,7 @@ void TraceLog::SendToATrace(char phase, if (flags & TRACE_EVENT_FLAG_HAS_ID) StringAppendF(&out, "-%" PRIx64, static_cast<uint64>(id)); StringAppendF(&out, "|%d|%s", - static_cast<int>(arg_values[i]), category); + static_cast<int>(arg_values[i]), category_group); write(g_atrace_fd, out.c_str(), out.size()); } break; @@ -126,11 +126,11 @@ void TraceLog::SendToATrace(char phase, } // Must be called with lock_ locked. -void TraceLog::ApplyATraceEnabledFlag(unsigned char* category_enabled) { +void TraceLog::ApplyATraceEnabledFlag(unsigned char* category_group_enabled) { if (g_atrace_fd != -1) - *category_enabled |= ATRACE_ENABLED; + *category_group_enabled |= ATRACE_ENABLED; else - *category_enabled &= ~ATRACE_ENABLED; + *category_group_enabled &= ~ATRACE_ENABLED; } } // namespace debug diff --git a/base/debug/trace_event_impl.cc b/base/debug/trace_event_impl.cc index f525d7c..96ef2c7 100644 --- a/base/debug/trace_event_impl.cc +++ b/base/debug/trace_event_impl.cc @@ -54,23 +54,24 @@ const size_t kTraceEventBufferSize = 500000; const size_t kTraceEventBatchSize = 1000; const size_t kTraceEventInitialBufferSize = 1024; -#define TRACE_EVENT_MAX_CATEGORIES 100 +#define MAX_CATEGORY_GROUPS 100 namespace { -// Parallel arrays g_categories and g_category_enabled are separate so that -// a pointer to a member of g_category_enabled can be easily converted to an -// index into g_categories. This allows macros to deal only with char enabled -// pointers from g_category_enabled, and we can convert internally to determine -// the category name from the char enabled pointer. -const char* g_categories[TRACE_EVENT_MAX_CATEGORIES] = { +// Parallel arrays g_category_groups and g_category_group_enabled are separate +// so that a pointer to a member of g_category_group_enabled can be easily +// converted to an index into g_category_groups. This allows macros to deal +// only with char enabled pointers from g_category_group_enabled, and we can +// convert internally to determine the category name from the char enabled +// pointer. +const char* g_category_groups[MAX_CATEGORY_GROUPS] = { "tracing already shutdown", - "tracing categories exhausted; must increase TRACE_EVENT_MAX_CATEGORIES", + "tracing categories exhausted; must increase MAX_CATEGORY_GROUPS", "__metadata", }; // The enabled flag is char instead of bool so that the API can be used from C. -unsigned char g_category_enabled[TRACE_EVENT_MAX_CATEGORIES] = { 0 }; +unsigned char g_category_group_enabled[MAX_CATEGORY_GROUPS] = { 0 }; const int g_category_already_shutdown = 0; const int g_category_categories_exhausted = 1; const int g_category_metadata = 2; @@ -140,7 +141,7 @@ class TraceBufferRingBuffer : public TraceBuffer { size_t index = oldest_event_index_; while (index != unused_event_index_) { const TraceEvent& event = GetEventAt(index); - if (category == event.category_enabled() && + if (category == event.category_group_enabled() && strcmp(event_name.c_str(), event.name()) == 0) { ++notify_count; } @@ -203,7 +204,7 @@ class TraceBufferVector : public TraceBuffer { size_t notify_count = 0; for (size_t i = 0; i < Size(); i++) { const TraceEvent& event = GetEventAt(i); - if (category == event.category_enabled() && + if (category == event.category_group_enabled() && strcmp(event_name.c_str(), event.name()) == 0) { ++notify_count; } @@ -254,7 +255,7 @@ void CopyTraceEventParameter(char** buffer, TraceEvent::TraceEvent() : id_(0u), - category_enabled_(NULL), + category_group_enabled_(NULL), name_(NULL), thread_id_(0), phase_(TRACE_EVENT_PHASE_BEGIN), @@ -268,7 +269,7 @@ TraceEvent::TraceEvent( int thread_id, TimeTicks timestamp, char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, int num_args, @@ -279,7 +280,7 @@ TraceEvent::TraceEvent( unsigned char flags) : timestamp_(timestamp), id_(id), - category_enabled_(category_enabled), + category_group_enabled_(category_group_enabled), name_(name), thread_id_(thread_id), phase_(phase), @@ -352,7 +353,7 @@ TraceEvent::TraceEvent( TraceEvent::TraceEvent(const TraceEvent& other) : timestamp_(other.timestamp_), id_(other.id_), - category_enabled_(other.category_enabled_), + category_group_enabled_(other.category_group_enabled_), name_(other.name_), thread_id_(other.thread_id_), phase_(other.phase_), @@ -379,7 +380,7 @@ TraceEvent& TraceEvent::operator=(const TraceEvent& other) { timestamp_ = other.timestamp_; id_ = other.id_; - category_enabled_ = other.category_enabled_; + category_group_enabled_ = other.category_group_enabled_; name_ = other.name_; parameter_copy_storage_ = other.parameter_copy_storage_; thread_id_ = other.thread_id_; @@ -452,12 +453,12 @@ void TraceEvent::AppendValueAsJSON(unsigned char type, void TraceEvent::AppendAsJSON(std::string* out) const { int64 time_int64 = timestamp_.ToInternalValue(); int process_id = TraceLog::GetInstance()->process_id(); - // Category name checked at category creation time. + // Category group checked at category creation time. DCHECK(!strchr(name_, '"')); StringAppendF(out, "{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 "," "\"ph\":\"%c\",\"name\":\"%s\",\"args\":{", - TraceLog::GetCategoryName(category_enabled_), + TraceLog::GetCategoryGroupName(category_group_enabled_), process_id, thread_id_, time_int64, @@ -632,12 +633,12 @@ void TraceSamplingThread::DefaultSampleCallback(TraceBucketData* bucket_data) { return; const char* const combined = reinterpret_cast<const char* const>(category_and_name); - const char* category; + const char* category_group; const char* name; - ExtractCategoryAndName(combined, &category, &name); + ExtractCategoryAndName(combined, &category_group, &name); TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_SAMPLE, - TraceLog::GetCategoryEnabled(category), - name, 0, 0, NULL, NULL, NULL, NULL, 0); + TraceLog::GetCategoryGroupEnabled(category_group), + name, 0, 0, NULL, NULL, NULL, NULL, 0); } void TraceSamplingThread::GetSamples() { @@ -747,16 +748,18 @@ TraceLog::TraceLog() dispatching_to_observer_list_(false), watch_category_(NULL), trace_options_(RECORD_UNTIL_FULL), - sampling_thread_handle_(0) { + sampling_thread_handle_(0), + category_filter_(CategoryFilter::kDefaultCategoryFilterString) { // 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 // macros fast. // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: - // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled), - // "trace_event category enabled"); - for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) { - ANNOTATE_BENIGN_RACE(&g_category_enabled[i], + // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled, + // sizeof(g_category_group_enabled), + // "trace_event category enabled"); + for (int i = 0; i < MAX_CATEGORY_GROUPS; ++i) { + ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i], "trace_event category enabled"); } #if defined(OS_NACL) // NaCl shouldn't expose the process id. @@ -771,112 +774,100 @@ TraceLog::TraceLog() TraceLog::~TraceLog() { } -const unsigned char* TraceLog::GetCategoryEnabled(const char* name) { +const unsigned char* TraceLog::GetCategoryGroupEnabled( + const char* category_group) { TraceLog* tracelog = GetInstance(); if (!tracelog) { - DCHECK(!g_category_enabled[g_category_already_shutdown]); - return &g_category_enabled[g_category_already_shutdown]; + DCHECK(!g_category_group_enabled[g_category_already_shutdown]); + return &g_category_group_enabled[g_category_already_shutdown]; } - return tracelog->GetCategoryEnabledInternal(name); + return tracelog->GetCategoryGroupEnabledInternal(category_group); } -const char* TraceLog::GetCategoryName(const unsigned char* category_enabled) { - // Calculate the index of the category by finding category_enabled in - // g_category_enabled array. - uintptr_t category_begin = reinterpret_cast<uintptr_t>(g_category_enabled); - uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_enabled); +const char* TraceLog::GetCategoryGroupName( + const unsigned char* category_group_enabled) { + // Calculate the index of the category group by finding + // category_group_enabled in g_category_group_enabled array. + uintptr_t category_begin = + reinterpret_cast<uintptr_t>(g_category_group_enabled); + uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_group_enabled); DCHECK(category_ptr >= category_begin && - category_ptr < reinterpret_cast<uintptr_t>(g_category_enabled + - TRACE_EVENT_MAX_CATEGORIES)) << + category_ptr < reinterpret_cast<uintptr_t>( + g_category_group_enabled + MAX_CATEGORY_GROUPS)) << "out of bounds category pointer"; uintptr_t category_index = - (category_ptr - category_begin) / sizeof(g_category_enabled[0]); - return g_categories[category_index]; -} - -static void EnableMatchingCategory(int category_index, - const std::vector<std::string>& patterns, - unsigned char matched_value, - unsigned char unmatched_value) { - std::vector<std::string>::const_iterator ci = patterns.begin(); - bool is_match = false; - for (; ci != patterns.end(); ++ci) { - is_match = MatchPattern(g_categories[category_index], ci->c_str()); - if (is_match) - break; - } - g_category_enabled[category_index] = is_match ? - matched_value : unmatched_value; + (category_ptr - category_begin) / sizeof(g_category_group_enabled[0]); + return g_category_groups[category_index]; } -// Enable/disable each category based on the category filters in |patterns|. -// If the category name matches one of the patterns, its enabled status is set -// to |matched_value|. Otherwise its enabled status is set to |unmatched_value|. -static void EnableMatchingCategories(const std::vector<std::string>& patterns, - unsigned char matched_value, - unsigned char unmatched_value) { +void TraceLog::EnableIncludedCategoryGroup(int category_index) { + bool is_enabled = category_filter_.IsCategoryGroupEnabled( + g_category_groups[category_index]); + g_category_group_enabled[category_index] = + is_enabled ? TraceLog::CATEGORY_ENABLED : 0; +} + +void TraceLog::EnableIncludedCategoryGroups() { for (int i = 0; i < g_category_index; i++) - EnableMatchingCategory(i, patterns, matched_value, unmatched_value); + EnableIncludedCategoryGroup(i); } -const unsigned char* TraceLog::GetCategoryEnabledInternal(const char* name) { +const unsigned char* TraceLog::GetCategoryGroupEnabledInternal( + const char* category_group) { + DCHECK(!strchr(category_group, '"')) << + "Category groups may not contain double quote"; AutoLock lock(lock_); - DCHECK(!strchr(name, '"')) << "Category names may not contain double quote"; - unsigned char* category_enabled = NULL; - // Search for pre-existing category matching this name + unsigned char* category_group_enabled = NULL; + // Search for pre-existing category group. for (int i = 0; i < g_category_index; i++) { - if (strcmp(g_categories[i], name) == 0) { - category_enabled = &g_category_enabled[i]; + if (strcmp(g_category_groups[i], category_group) == 0) { + category_group_enabled = &g_category_group_enabled[i]; break; } } - if (!category_enabled) { - // Create a new category - DCHECK(g_category_index < TRACE_EVENT_MAX_CATEGORIES) << - "must increase TRACE_EVENT_MAX_CATEGORIES"; - if (g_category_index < TRACE_EVENT_MAX_CATEGORIES) { + if (!category_group_enabled) { + // Create a new category group + DCHECK(g_category_index < MAX_CATEGORY_GROUPS) << + "must increase MAX_CATEGORY_GROUPS"; + if (g_category_index < MAX_CATEGORY_GROUPS) { int new_index = g_category_index++; - // Don't hold on to the name pointer, so that we can create categories - // with strings not known at compile time (this is required by - // SetWatchEvent). - const char* new_name = strdup(name); - ANNOTATE_LEAKING_OBJECT_PTR(new_name); - g_categories[new_index] = new_name; - DCHECK(!g_category_enabled[new_index]); + // Don't hold on to the category_group pointer, so that we can create + // category groups with strings not known at compile time (this is + // required by SetWatchEvent). + const char* new_group = strdup(category_group); + ANNOTATE_LEAKING_OBJECT_PTR(new_group); + g_category_groups[new_index] = new_group; + DCHECK(!g_category_group_enabled[new_index]); if (enable_count_) { - // Note that if both included and excluded_categories are empty, the - // else clause below excludes nothing, thereby enabling this category. - if (!included_categories_.empty()) { - EnableMatchingCategory(new_index, included_categories_, - CATEGORY_ENABLED, 0); - } else { - EnableMatchingCategory(new_index, excluded_categories_, - 0, CATEGORY_ENABLED); - } + // Note that if both included and excluded patterns in the + // CategoryFilter are empty, we exclude nothing, + // thereby enabling this category group. + EnableIncludedCategoryGroup(new_index); } else { - g_category_enabled[new_index] = 0; + g_category_group_enabled[new_index] = 0; } - category_enabled = &g_category_enabled[new_index]; + category_group_enabled = &g_category_group_enabled[new_index]; } else { - category_enabled = &g_category_enabled[g_category_categories_exhausted]; + category_group_enabled = + &g_category_group_enabled[g_category_categories_exhausted]; } } #if defined(OS_ANDROID) - ApplyATraceEnabledFlag(category_enabled); + ApplyATraceEnabledFlag(category_group_enabled); #endif - return category_enabled; + return category_group_enabled; } -void TraceLog::GetKnownCategories(std::vector<std::string>* categories) { +void TraceLog::GetKnownCategoryGroups( + std::vector<std::string>* category_groups) { AutoLock lock(lock_); - for (int i = g_num_builtin_categories; i < g_category_index; i++) - categories->push_back(g_categories[i]); + for (int i = 0; i < g_category_index; i++) + category_groups->push_back(g_category_groups[i]); } -void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, - const std::vector<std::string>& excluded_categories, +void TraceLog::SetEnabled(const CategoryFilter& category_filter, Options options) { AutoLock lock(lock_); @@ -888,17 +879,14 @@ void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, // 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()) { - included_categories_.insert(included_categories_.end(), - included_categories.begin(), - included_categories.end()); - EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); + if (category_filter_.HasIncludedPatterns() && + category_filter.HasIncludedPatterns()) { + category_filter_.Merge(category_filter); } else { // If either old or new included categories are empty, allow all events. - included_categories_.clear(); - excluded_categories_.clear(); - EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); + category_filter_.Clear(); } + EnableIncludedCategoryGroups(); return; } @@ -918,14 +906,8 @@ void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, OnTraceLogWillEnable()); dispatching_to_observer_list_ = false; - included_categories_ = included_categories; - excluded_categories_ = excluded_categories; - // Note that if both included and excluded_categories are empty, the else - // clause below excludes nothing, thereby enabling all categories. - if (!included_categories_.empty()) - EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); - else - EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); + category_filter_ = CategoryFilter(category_filter); + EnableIncludedCategoryGroups(); if (options & ENABLE_SAMPLING) { sampling_thread_.reset(new TraceSamplingThread); @@ -948,35 +930,10 @@ void TraceLog::SetEnabled(const std::vector<std::string>& included_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, ","); - while (tokens.GetNext()) { - bool is_included = true; - std::string category = tokens.token(); - // Excluded categories start with '-'. - if (category.at(0) == '-') { - // Remove '-' from category string. - category = category.substr(1); - is_included = false; - } - if (is_included) - included.push_back(category); - else - excluded.push_back(category); - } - SetEnabled(included, excluded, options); -} - -void TraceLog::GetEnabledTraceCategories( - std::vector<std::string>* included_out, - std::vector<std::string>* excluded_out) { +const CategoryFilter& TraceLog::GetCurrentCategoryFilter() { AutoLock lock(lock_); - if (enable_count_) { - *included_out = included_categories_; - *excluded_out = excluded_categories_; - } + DCHECK(enable_count_ > 0); + return category_filter_; } void TraceLog::SetDisabled() { @@ -1007,22 +964,14 @@ void TraceLog::SetDisabled() { OnTraceLogWillDisable()); dispatching_to_observer_list_ = false; - included_categories_.clear(); - excluded_categories_.clear(); + category_filter_.Clear(); watch_category_ = NULL; watch_event_name_ = ""; for (int i = 0; i < g_category_index; i++) - g_category_enabled[i] = 0; + g_category_group_enabled[i] = 0; AddThreadNameMetadataEvents(); } -void TraceLog::SetEnabled(bool enabled, Options options) { - if (enabled) - SetEnabled(std::vector<std::string>(), std::vector<std::string>(), options); - else - SetDisabled(); -} - void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) { enabled_state_observer_list_.AddObserver(listener); } @@ -1082,7 +1031,7 @@ void TraceLog::Flush(const TraceLog::OutputCallback& cb) { void TraceLog::AddTraceEvent( char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, int num_args, @@ -1093,7 +1042,7 @@ void TraceLog::AddTraceEvent( unsigned char flags) { int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime(); - AddTraceEventWithThreadIdAndTimestamp(phase, category_enabled, name, id, + AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, name, id, thread_id, now, num_args, arg_names, arg_types, arg_values, convertable_values, flags); @@ -1101,7 +1050,7 @@ void TraceLog::AddTraceEvent( void TraceLog::AddTraceEventWithThreadIdAndTimestamp( char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, int thread_id, @@ -1118,7 +1067,7 @@ void TraceLog::AddTraceEventWithThreadIdAndTimestamp( id ^= process_id_hash_; #if defined(OS_ANDROID) - SendToATrace(phase, GetCategoryName(category_enabled), name, id, + SendToATrace(phase, GetCategoryGroupName(category_group_enabled), name, id, num_args, arg_names, arg_types, arg_values, flags); #endif @@ -1129,7 +1078,7 @@ void TraceLog::AddTraceEventWithThreadIdAndTimestamp( { AutoLock lock(lock_); - if (*category_enabled != CATEGORY_ENABLED) + if (*category_group_enabled != CATEGORY_ENABLED) return; if (logged_events_->IsFull()) return; @@ -1165,14 +1114,14 @@ void TraceLog::AddTraceEventWithThreadIdAndTimestamp( } logged_events_->AddEvent(TraceEvent(thread_id, - now, phase, category_enabled, name, id, + now, phase, category_group_enabled, name, id, num_args, arg_names, arg_types, arg_values, convertable_values, flags)); if (logged_events_->IsFull()) notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL); - if (watch_category_ == category_enabled && watch_event_name_ == name) + if (watch_category_ == category_group_enabled && watch_event_name_ == name) notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION); event_callback_copy = event_callback_; @@ -1180,7 +1129,7 @@ void TraceLog::AddTraceEventWithThreadIdAndTimestamp( notifier.SendNotificationIfAny(); if (event_callback_copy != NULL) { - event_callback_copy(phase, category_enabled, name, id, + event_callback_copy(phase, category_group_enabled, name, id, num_args, arg_names, arg_types, arg_values, flags); } @@ -1211,7 +1160,8 @@ void TraceLog::AddTraceEventEtw(char phase, void TraceLog::SetWatchEvent(const std::string& category_name, const std::string& event_name) { - const unsigned char* category = GetCategoryEnabled(category_name.c_str()); + const unsigned char* category = GetCategoryGroupEnabled( + category_name.c_str()); size_t notify_count = 0; { AutoLock lock(lock_); @@ -1252,7 +1202,7 @@ void TraceLog::AddThreadNameMetadataEvents() { trace_event_internal::SetTraceValue(it->second, &arg_type, &arg_value); logged_events_->AddEvent(TraceEvent(it->first, TimeTicks(), TRACE_EVENT_PHASE_METADATA, - &g_category_enabled[g_category_metadata], + &g_category_group_enabled[g_category_metadata], "thread_name", trace_event_internal::kNoEventId, num_args, &arg_name, &arg_type, &arg_value, NULL, TRACE_EVENT_FLAG_NONE)); @@ -1287,6 +1237,145 @@ void TraceLog::SetTimeOffset(TimeDelta offset) { time_offset_ = offset; } +bool CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( + const std::string& str) { + return str.empty() || + str.at(0) == ' ' || + str.at(str.length() - 1) == ' '; +} + +static bool DoesCategoryGroupContainCategory(const char* category_group, + const char* category) { + DCHECK(category); + CStringTokenizer category_group_tokens(category_group, + category_group + strlen(category_group), ","); + while (category_group_tokens.GetNext()) { + std::string category_group_token = category_group_tokens.token(); + // Don't allow empty tokens, nor tokens with leading or trailing space. + DCHECK(!CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( + category_group_token)) + << "Disallowed category string"; + if (MatchPattern(category_group_token.c_str(), category)) + return true; + } + return false; +} + +// Enable everything but debug and test categories by default. +const char* CategoryFilter::kDefaultCategoryFilterString = "-*Debug,-*Test"; + +CategoryFilter::CategoryFilter(const std::string& filter_string) { + if (!filter_string.empty()) + Initialize(filter_string); + else + Initialize(CategoryFilter::kDefaultCategoryFilterString); +} + +CategoryFilter::CategoryFilter(const CategoryFilter& cf) + : included_(cf.included_), + excluded_(cf.excluded_) { +} + +CategoryFilter::~CategoryFilter() { +} + +CategoryFilter& CategoryFilter::operator=(const CategoryFilter& rhs) { + if (this == &rhs) + return *this; + + included_ = rhs.included_; + excluded_ = rhs.excluded_; + return *this; +} + +void CategoryFilter::Initialize(const std::string& filter_string) { + // Tokenize list of categories, delimited by ','. + StringTokenizer tokens(filter_string, ","); + // Add each token to the appropriate list (included_,excluded_). + while (tokens.GetNext()) { + std::string category = tokens.token(); + // Ignore empty categories. + if (category.empty()) + continue; + // Excluded categories start with '-'. + if (category.at(0) == '-') { + // Remove '-' from category string. + category = category.substr(1); + excluded_.push_back(category); + } else { + included_.push_back(category); + } + } +} + +void CategoryFilter::WriteString(std::string* out, + bool included) const { + std::vector<std::string>::const_iterator ci; + std::vector<std::string>::const_iterator end; + if (included) { + ci = included_.begin(); + end = included_.end(); + } else { + ci = excluded_.begin(); + end = excluded_.end(); + } + + // Prepend commas for all excluded categories IF we have included categories. + bool prepend_comma_for_first_excluded = !included && !included_.empty(); + int token_cnt = 0; + for (; ci != end; ++ci) { + if (token_cnt > 0 || prepend_comma_for_first_excluded) + StringAppendF(out, ","); + StringAppendF(out, "%s%s", (included ? "" : "-"), ci->c_str()); + ++token_cnt; + } +} + +std::string CategoryFilter::ToString() const { + std::string filter_string; + WriteString(&filter_string, true); + WriteString(&filter_string, false); + + return filter_string; +} + +bool CategoryFilter::IsCategoryGroupEnabled( + const char* category_group_name) const { + // TraceLog should call this method only as part of enabling/disabling + // categories. + std::vector<std::string>::const_iterator ci = included_.begin(); + for (; ci != included_.end(); ++ci) { + if (DoesCategoryGroupContainCategory(category_group_name, ci->c_str())) + return true; + } + ci = excluded_.begin(); + for (; ci != excluded_.end(); ++ci) { + if (DoesCategoryGroupContainCategory(category_group_name, ci->c_str())) + return false; + } + // If the category group is not excluded, and there are no included patterns + // we consider this pattern enabled. + return included_.empty(); +} + +void CategoryFilter::Merge(const CategoryFilter& nested_filter) { + included_.insert(included_.end(), + nested_filter.included_.begin(), + nested_filter.included_.end()); + excluded_.insert(excluded_.end(), + nested_filter.excluded_.begin(), + nested_filter.excluded_.end()); +} + +bool CategoryFilter::HasIncludedPatterns() const { + return !included_.empty(); +} + +void CategoryFilter::Clear() { + included_.clear(); + excluded_.clear(); +} + } // namespace debug } // namespace base @@ -1294,20 +1383,20 @@ namespace trace_event_internal { ScopedTrace::ScopedTrace( TRACE_EVENT_API_ATOMIC_WORD* event_uid, const char* name) { - category_enabled_ = + category_group_enabled_ = reinterpret_cast<const unsigned char*>(TRACE_EVENT_API_ATOMIC_LOAD( *event_uid)); - if (!category_enabled_) { - category_enabled_ = TRACE_EVENT_API_GET_CATEGORY_ENABLED("gpu"); + if (!category_group_enabled_) { + category_group_enabled_ = TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("gpu"); TRACE_EVENT_API_ATOMIC_STORE( *event_uid, - reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>(category_enabled_)); + reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>(category_group_enabled_)); } - if (*category_enabled_) { + if (*category_group_enabled_) { name_ = name; TRACE_EVENT_API_ADD_TRACE_EVENT( TRACE_EVENT_PHASE_BEGIN, // phase - category_enabled_, // category enabled + category_group_enabled_, // category enabled name, // name 0, // id 0, // num_args @@ -1317,15 +1406,15 @@ ScopedTrace::ScopedTrace( NULL, // convertable_values TRACE_EVENT_FLAG_NONE); // flags } else { - category_enabled_ = NULL; + category_group_enabled_ = NULL; } } ScopedTrace::~ScopedTrace() { - if (category_enabled_ && *category_enabled_) { + if (category_group_enabled_ && *category_group_enabled_) { TRACE_EVENT_API_ADD_TRACE_EVENT( TRACE_EVENT_PHASE_END, // phase - category_enabled_, // category enabled + category_group_enabled_, // category enabled name_, // name 0, // id 0, // num_args diff --git a/base/debug/trace_event_impl.h b/base/debug/trace_event_impl.h index d9f8f1c..c0eead0 100644 --- a/base/debug/trace_event_impl.h +++ b/base/debug/trace_event_impl.h @@ -80,7 +80,7 @@ class BASE_EXPORT TraceEvent { TraceEvent(int thread_id, TimeTicks timestamp, char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, int num_args, @@ -112,7 +112,10 @@ class BASE_EXPORT TraceEvent { return parameter_copy_storage_.get(); } - const unsigned char* category_enabled() const { return category_enabled_; } + const unsigned char* category_group_enabled() const { + return category_group_enabled_; + } + const char* name() const { return name_; } private: @@ -123,7 +126,7 @@ class BASE_EXPORT TraceEvent { TraceValue arg_values_[kTraceMaxNumArgs]; const char* arg_names_[kTraceMaxNumArgs]; scoped_ptr<ConvertableToTraceFormat> convertable_values_[kTraceMaxNumArgs]; - const unsigned char* category_enabled_; + const unsigned char* category_group_enabled_; const char* name_; scoped_refptr<base::RefCountedString> parameter_copy_storage_; int thread_id_; @@ -190,6 +193,67 @@ class BASE_EXPORT TraceResultBuffer { bool append_comma_; }; +class BASE_EXPORT CategoryFilter { + public: + // The default category filter, used when none is provided. + // Allows all categories through, except if they end in the suffix 'Debug' or + // 'Test'. + static const char* kDefaultCategoryFilterString; + + // |filter_string| is a comma-delimited list of category wildcards. + // A category can have an optional '-' prefix to make it an excluded category. + // All the same rules apply above, so for example, having both included and + // excluded categories in the same list would not be supported. + // + // Example: CategoryFilter"test_MyTest*"); + // Example: CategoryFilter("test_MyTest*,test_OtherStuff"); + // Example: CategoryFilter("-excluded_category1,-excluded_category2"); + // Example: CategoryFilter("-*,webkit"); would disable everything but webkit. + // Example: CategoryFilter("-webkit"); would enable everything but webkit. + explicit CategoryFilter(const std::string& filter_string); + + CategoryFilter(const CategoryFilter& cf); + + ~CategoryFilter(); + + CategoryFilter& operator=(const CategoryFilter& rhs); + + // Writes the string representation of the CategoryFilter. This is a comma + // separated string, similar in nature to the one used to determine + // enabled/disabled category patterns, except here there is an arbitrary + // order, included categories go first, then excluded categories. Excluded + // categories are distinguished from included categories by the prefix '-'. + std::string ToString() const; + + // Determines whether category group would be enabled or + // disabled by this category filter. + bool IsCategoryGroupEnabled(const char* category_group) const; + + // Merges nested_filter with the current CategoryFilter + void Merge(const CategoryFilter& nested_filter); + + // Determines whether or not we have explicitly allowed category patterns. + bool HasIncludedPatterns() const; + + // Clears both included/excluded pattern lists. This would be equivalent to + // creating a CategoryFilter with an empty string, through the constructor. + // i.e: CategoryFilter(""). + // + // When using an empty filter, all categories are considered included as we + // are not excluding anything. + void Clear(); + + static bool IsEmptyOrContainsLeadingOrTrailingWhitespace( + const std::string& str); + + private: + void Initialize(const std::string& filter_string); + void WriteString(std::string* out, bool included) const; + + std::vector<std::string> included_; + std::vector<std::string> excluded_; +}; + class TraceSamplingThread; class BASE_EXPORT TraceLog { @@ -223,43 +287,21 @@ class BASE_EXPORT TraceLog { // 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); - - // Enable tracing for provided list of categories. If tracing is already - // enabled, this method does nothing -- changing categories during trace is - // not supported. - // If both included_categories and excluded_categories are empty, - // all categories are traced. - // Else if included_categories is non-empty, only those are traced. - // 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, - Options options); - - // |categories| is a comma-delimited list of category wildcards. - // A category can have an optional '-' prefix to make it an excluded category. - // All the same rules apply above, so for example, having both included and - // excluded categories in the same list would not be supported. - // - // Example: SetEnabled("test_MyTest*"); - // Example: SetEnabled("test_MyTest*,test_OtherStuff"); - // Example: SetEnabled("-excluded_category1,-excluded_category2"); - void SetEnabled(const std::string& categories, Options options); + // Get set of known category groups. This can change as new code paths are + // reached. The known category groups are inserted into |category_groups|. + void GetKnownCategoryGroups(std::vector<std::string>* category_groups); - // 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); + // Retrieves the current CategoryFilter. + const CategoryFilter& GetCurrentCategoryFilter(); Options trace_options() const { return trace_options_; } + // Enables tracing. See CategoryFilter comments for details + // on how to control what categories will be traced. + void SetEnabled(const CategoryFilter& category_filter, Options options); + // Disable tracing for all categories. void SetDisabled(); - // Helper method to enable/disable tracing for all categories. - void SetEnabled(bool enabled, Options options); bool IsEnabled() { return !!enable_count_; } #if defined(OS_ANDROID) @@ -302,7 +344,7 @@ class BASE_EXPORT TraceLog { // after a call to SetEventCallback() that replaces or clears the callback. // This callback may be invoked on any thread. typedef void (*EventCallback)(char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, int num_args, @@ -321,15 +363,18 @@ class BASE_EXPORT TraceLog { void Flush(const OutputCallback& cb); // Called by TRACE_EVENT* macros, don't call this directly. - static const unsigned char* GetCategoryEnabled(const char* name); - static const char* GetCategoryName(const unsigned char* category_enabled); + // The name parameter is a category group for example: + // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") + static const unsigned char* GetCategoryGroupEnabled(const char* name); + static const char* GetCategoryGroupName( + const unsigned char* category_group_enabled); // Called by TRACE_EVENT* macros, don't call this directly. // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above. void AddTraceEvent(char phase, - const unsigned char* category_enabled, - const char* name, + const unsigned char* category_group_enabled, + const char* category_group, unsigned long long id, int num_args, const char** arg_names, @@ -339,7 +384,7 @@ class BASE_EXPORT TraceLog { unsigned char flags); void AddTraceEventWithThreadIdAndTimestamp( char phase, - const unsigned char* category_enabled, + const unsigned char* category_group_enabled, const char* name, unsigned long long id, int thread_id, @@ -351,11 +396,11 @@ class BASE_EXPORT TraceLog { scoped_ptr<ConvertableToTraceFormat> convertable_values[], unsigned char flags); static void AddTraceEventEtw(char phase, - const char* name, + const char* category_group, const void* id, const char* extra); static void AddTraceEventEtw(char phase, - const char* name, + const char* category_group, const void* id, const std::string& extra); @@ -398,8 +443,14 @@ class BASE_EXPORT TraceLog { // by the Singleton class. friend struct StaticMemorySingletonTraits<TraceLog>; - // The pointer returned from GetCategoryEnabledInternal() points to a value - // with zero or more of the following bits. Used in this class only. + // Enable/disable each category group based on the current category_filter_. + // If the category group contains a category that matches an included category + // pattern, that category group will be enabled. + void EnableIncludedCategoryGroups(); + void EnableIncludedCategoryGroup(int category_index); + + // The pointer returned from GetCategoryGroupEnabledInternal() points to a + // value with zero or more of the following bits. Used in this class only. // The TRACE_EVENT macros should only use the value as a bool. enum CategoryEnabledFlags { // Normal enabled flag for categories enabled with Enable(). @@ -434,12 +485,12 @@ class BASE_EXPORT TraceLog { TraceLog(); ~TraceLog(); - const unsigned char* GetCategoryEnabledInternal(const char* name); + const unsigned char* GetCategoryGroupEnabledInternal(const char* name); void AddThreadNameMetadataEvents(); #if defined(OS_ANDROID) void SendToATrace(char phase, - const char* category, + const char* category_group, const char* name, unsigned long long id, int num_args, @@ -447,7 +498,7 @@ class BASE_EXPORT TraceLog { const unsigned char* arg_types, const unsigned long long* arg_values, unsigned char flags); - static void ApplyATraceEnabledFlag(unsigned char* category_enabled); + static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled); #endif TraceBuffer* GetTraceBuffer(); @@ -460,8 +511,6 @@ class BASE_EXPORT TraceLog { NotificationCallback notification_callback_; scoped_ptr<TraceBuffer> logged_events_; EventCallback event_callback_; - std::vector<std::string> included_categories_; - std::vector<std::string> excluded_categories_; bool dispatching_to_observer_list_; ObserverList<EnabledStateChangedObserver> enabled_state_observer_list_; @@ -484,6 +533,8 @@ class BASE_EXPORT TraceLog { scoped_ptr<TraceSamplingThread> sampling_thread_; PlatformThreadHandle sampling_thread_handle_; + CategoryFilter category_filter_; + DISALLOW_COPY_AND_ASSIGN(TraceLog); }; diff --git a/base/debug/trace_event_unittest.cc b/base/debug/trace_event_unittest.cc index c682216..82c8dc0 100644 --- a/base/debug/trace_event_unittest.cc +++ b/base/debug/trace_event_unittest.cc @@ -73,7 +73,7 @@ class TraceEventTestFixture : public testing::Test { void BeginTrace() { event_watch_notification_ = 0; - TraceLog::GetInstance()->SetEnabled(std::string("*"), + TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"), TraceLog::RECORD_UNTIL_FULL); } @@ -773,7 +773,8 @@ 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::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"), + TraceLog::RECORD_UNTIL_FULL); TraceWithAllMacroVariants(NULL); @@ -797,18 +798,20 @@ TEST_F(TraceEventTestFixture, EnabledObserverFiresOnEnable) { EXPECT_CALL(observer, OnTraceLogWillEnable()) .Times(1); - TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"), + TraceLog::RECORD_UNTIL_FULL); testing::Mock::VerifyAndClear(&observer); // Cleanup. TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer); - TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetDisabled(); } TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnSecondEnable) { ManualTestSetUp(); - TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"), + TraceLog::RECORD_UNTIL_FULL); testing::StrictMock<MockEnabledStateChangedObserver> observer; TraceLog::GetInstance()->AddEnabledStateObserver(&observer); @@ -817,20 +820,22 @@ TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnSecondEnable) { .Times(0); EXPECT_CALL(observer, OnTraceLogWillDisable()) .Times(0); - TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"), + TraceLog::RECORD_UNTIL_FULL); testing::Mock::VerifyAndClear(&observer); // Cleanup. TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer); - TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL); - TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetDisabled(); + TraceLog::GetInstance()->SetDisabled(); } TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnNestedDisable) { ManualTestSetUp(); - TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); - TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); + CategoryFilter cf_inc_all("*"); + TraceLog::GetInstance()->SetEnabled(cf_inc_all, TraceLog::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetEnabled(cf_inc_all, TraceLog::RECORD_UNTIL_FULL); testing::StrictMock<MockEnabledStateChangedObserver> observer; TraceLog::GetInstance()->AddEnabledStateObserver(&observer); @@ -839,25 +844,26 @@ TEST_F(TraceEventTestFixture, EnabledObserverDoesntFireOnNestedDisable) { .Times(0); EXPECT_CALL(observer, OnTraceLogWillDisable()) .Times(0); - TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetDisabled(); testing::Mock::VerifyAndClear(&observer); // Cleanup. TraceLog::GetInstance()->RemoveEnabledStateObserver(&observer); - TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetDisabled(); } TEST_F(TraceEventTestFixture, EnabledObserverFiresOnDisable) { ManualTestSetUp(); - TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"), + TraceLog::RECORD_UNTIL_FULL); MockEnabledStateChangedObserver observer; TraceLog::GetInstance()->AddEnabledStateObserver(&observer); EXPECT_CALL(observer, OnTraceLogWillDisable()) .Times(1); - TraceLog::GetInstance()->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetDisabled(); testing::Mock::VerifyAndClear(&observer); // Cleanup. @@ -875,15 +881,26 @@ TEST_F(TraceEventTestFixture, Categories) { BeginTrace(); TRACE_EVENT_INSTANT0("c3", "name", TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("c4", "name", TRACE_EVENT_SCOPE_THREAD); + // Category groups containing more than one category. + TRACE_EVENT_INSTANT0("c5,c6", "name", TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_INSTANT0("c7,c8", "name", TRACE_EVENT_SCOPE_THREAD); + EndTraceAndFlush(); - std::vector<std::string> cats; - TraceLog::GetInstance()->GetKnownCategories(&cats); - EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c1") != cats.end()); - EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c2") != cats.end()); - EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c3") != cats.end()); - EXPECT_TRUE(std::find(cats.begin(), cats.end(), "c4") != cats.end()); - // Make sure metadata isn't returned. - EXPECT_TRUE(std::find(cats.begin(), cats.end(), "__metadata") == cats.end()); + std::vector<std::string> cat_groups; + TraceLog::GetInstance()->GetKnownCategoryGroups(&cat_groups); + EXPECT_TRUE(std::find(cat_groups.begin(), + cat_groups.end(), "c1") != cat_groups.end()); + EXPECT_TRUE(std::find(cat_groups.begin(), + cat_groups.end(), "c2") != cat_groups.end()); + EXPECT_TRUE(std::find(cat_groups.begin(), + cat_groups.end(), "c3") != cat_groups.end()); + EXPECT_TRUE(std::find(cat_groups.begin(), + cat_groups.end(), "c4") != cat_groups.end()); + EXPECT_TRUE(std::find(cat_groups.begin(), + cat_groups.end(), "c5,c6") != cat_groups.end()); + EXPECT_TRUE(std::find(cat_groups.begin(), + cat_groups.end(), "c7,c8") != cat_groups.end()); + const std::vector<std::string> empty_categories; std::vector<std::string> included_categories; std::vector<std::string> excluded_categories; @@ -893,8 +910,7 @@ TEST_F(TraceEventTestFixture, Categories) { // Include nonexistent category -> no events Clear(); included_categories.clear(); - included_categories.push_back("not_found823564786"); - TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories, + TraceLog::GetInstance()->SetEnabled(CategoryFilter("not_found823564786"), TraceLog::RECORD_UNTIL_FULL); TRACE_EVENT_INSTANT0("cat1", "name", TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("cat2", "name", TRACE_EVENT_SCOPE_THREAD); @@ -904,8 +920,7 @@ TEST_F(TraceEventTestFixture, Categories) { // Include existent category -> only events of that category Clear(); included_categories.clear(); - included_categories.push_back("inc"); - TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories, + TraceLog::GetInstance()->SetEnabled(CategoryFilter("inc"), TraceLog::RECORD_UNTIL_FULL); TRACE_EVENT_INSTANT0("inc", "name", TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("inc2", "name", TRACE_EVENT_SCOPE_THREAD); @@ -916,64 +931,73 @@ TEST_F(TraceEventTestFixture, Categories) { // Include existent wildcard -> all categories matching wildcard Clear(); included_categories.clear(); - included_categories.push_back("inc_wildcard_*"); - included_categories.push_back("inc_wildchar_?_end"); - TraceLog::GetInstance()->SetEnabled(included_categories, empty_categories, - TraceLog::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetEnabled( + CategoryFilter("inc_wildcard_*,inc_wildchar_?_end"), + TraceLog::RECORD_UNTIL_FULL); TRACE_EVENT_INSTANT0("inc_wildcard_abc", "included", - TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("inc_wildcard_", "included", TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "included", - TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "not_inc", - TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("cat1", "not_inc", TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("cat2", "not_inc", TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_INSTANT0("inc_wildcard_category,other_category", "included", + TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_INSTANT0( + "non_included_category,inc_wildcard_category", "included", + TRACE_EVENT_SCOPE_THREAD); EndTraceAndFlush(); EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_abc")); EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_")); EXPECT_TRUE(FindMatchingValue("cat", "inc_wildchar_x_end")); EXPECT_FALSE(FindMatchingValue("name", "not_inc")); + EXPECT_TRUE(FindMatchingValue("cat", "inc_wildcard_category,other_category")); + EXPECT_TRUE(FindMatchingValue("cat", + "non_included_category,inc_wildcard_category")); included_categories.clear(); // Exclude nonexistent category -> all events Clear(); - excluded_categories.clear(); - excluded_categories.push_back("not_found823564786"); - TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories, + TraceLog::GetInstance()->SetEnabled(CategoryFilter("-not_found823564786"), TraceLog::RECORD_UNTIL_FULL); TRACE_EVENT_INSTANT0("cat1", "name", TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("cat2", "name", TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_INSTANT0("category1,category2", "name", TRACE_EVENT_SCOPE_THREAD); EndTraceAndFlush(); EXPECT_TRUE(FindMatchingValue("cat", "cat1")); EXPECT_TRUE(FindMatchingValue("cat", "cat2")); + EXPECT_TRUE(FindMatchingValue("cat", "category1,category2")); // Exclude existent category -> only events of other categories Clear(); - excluded_categories.clear(); - excluded_categories.push_back("inc"); - TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories, + TraceLog::GetInstance()->SetEnabled(CategoryFilter("-inc"), TraceLog::RECORD_UNTIL_FULL); TRACE_EVENT_INSTANT0("inc", "name", TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("inc2", "name", TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_INSTANT0("inc2,inc", "name", TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_INSTANT0("inc,inc2", "name", TRACE_EVENT_SCOPE_THREAD); EndTraceAndFlush(); EXPECT_TRUE(FindMatchingValue("cat", "inc2")); EXPECT_FALSE(FindMatchingValue("cat", "inc")); + EXPECT_FALSE(FindMatchingValue("cat", "inc2,inc")); + EXPECT_FALSE(FindMatchingValue("cat", "inc,inc2")); // Exclude existent wildcard -> all categories not matching wildcard Clear(); - excluded_categories.clear(); - excluded_categories.push_back("inc_wildcard_*"); - excluded_categories.push_back("inc_wildchar_?_end"); - TraceLog::GetInstance()->SetEnabled(empty_categories, excluded_categories, - TraceLog::RECORD_UNTIL_FULL); - TRACE_EVENT_INSTANT0("inc_wildcard_abc", "not_inc", TRACE_EVENT_SCOPE_THREAD); - TRACE_EVENT_INSTANT0("inc_wildcard_", "not_inc", TRACE_EVENT_SCOPE_THREAD); + TraceLog::GetInstance()->SetEnabled( + CategoryFilter("-inc_wildcard_*,-inc_wildchar_?_end"), + TraceLog::RECORD_UNTIL_FULL); + TRACE_EVENT_INSTANT0("inc_wildcard_abc", "not_inc", + TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_INSTANT0("inc_wildcard_", "not_inc", + TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("inc_wildchar_x_end", "not_inc", - TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("inc_wildchar_bla_end", "included", - TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("cat1", "included", TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("cat2", "included", TRACE_EVENT_SCOPE_THREAD); EndTraceAndFlush(); @@ -1508,17 +1532,18 @@ TEST_F(TraceEventTestFixture, TraceEnableDisable) { ManualTestSetUp(); TraceLog* trace_log = TraceLog::GetInstance(); - trace_log->SetEnabled(std::string(), TraceLog::RECORD_UNTIL_FULL); + CategoryFilter cf_inc_all("*"); + trace_log->SetEnabled(cf_inc_all, TraceLog::RECORD_UNTIL_FULL); EXPECT_TRUE(trace_log->IsEnabled()); trace_log->SetDisabled(); EXPECT_FALSE(trace_log->IsEnabled()); - trace_log->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); + trace_log->SetEnabled(cf_inc_all, TraceLog::RECORD_UNTIL_FULL); EXPECT_TRUE(trace_log->IsEnabled()); const std::vector<std::string> empty; - trace_log->SetEnabled(empty, empty, TraceLog::RECORD_UNTIL_FULL); + trace_log->SetEnabled(CategoryFilter(""), TraceLog::RECORD_UNTIL_FULL); EXPECT_TRUE(trace_log->IsEnabled()); - trace_log->SetEnabled(false, TraceLog::RECORD_UNTIL_FULL); + trace_log->SetDisabled(); EXPECT_TRUE(trace_log->IsEnabled()); trace_log->SetDisabled(); EXPECT_FALSE(trace_log->IsEnabled()); @@ -1528,29 +1553,30 @@ TEST_F(TraceEventTestFixture, TraceCategoriesAfterNestedEnable) { ManualTestSetUp(); TraceLog* trace_log = TraceLog::GetInstance(); - 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"), TraceLog::RECORD_UNTIL_FULL); - EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo2")); - EXPECT_FALSE(*trace_log->GetCategoryEnabled("baz")); - trace_log->SetEnabled(std::string(), TraceLog::RECORD_UNTIL_FULL); - EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo")); - EXPECT_TRUE(*trace_log->GetCategoryEnabled("baz")); + trace_log->SetEnabled(CategoryFilter("foo,bar"), TraceLog::RECORD_UNTIL_FULL); + EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("foo")); + EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("bar")); + EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("baz")); + trace_log->SetEnabled(CategoryFilter("foo2"), TraceLog::RECORD_UNTIL_FULL); + EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("foo2")); + EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("baz")); + trace_log->SetEnabled(CategoryFilter(""), TraceLog::RECORD_UNTIL_FULL); + EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("foo")); + EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("baz")); trace_log->SetDisabled(); trace_log->SetDisabled(); trace_log->SetDisabled(); - EXPECT_FALSE(*trace_log->GetCategoryEnabled("foo")); - EXPECT_FALSE(*trace_log->GetCategoryEnabled("baz")); - - 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"), TraceLog::RECORD_UNTIL_FULL); - EXPECT_TRUE(*trace_log->GetCategoryEnabled("baz")); - EXPECT_TRUE(*trace_log->GetCategoryEnabled("moo")); - EXPECT_TRUE(*trace_log->GetCategoryEnabled("foo")); + EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("foo")); + EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("baz")); + + trace_log->SetEnabled(CategoryFilter("-foo,-bar"), + TraceLog::RECORD_UNTIL_FULL); + EXPECT_FALSE(*trace_log->GetCategoryGroupEnabled("foo")); + EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("baz")); + trace_log->SetEnabled(CategoryFilter("moo"), TraceLog::RECORD_UNTIL_FULL); + EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("baz")); + EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("moo")); + EXPECT_TRUE(*trace_log->GetCategoryGroupEnabled("foo")); trace_log->SetDisabled(); trace_log->SetDisabled(); } @@ -1572,7 +1598,7 @@ TEST_F(TraceEventTestFixture, TraceSampling) { event_watch_notification_ = 0; TraceLog::GetInstance()->SetEnabled( - std::string("*"), + CategoryFilter("*"), TraceLog::Options(TraceLog::RECORD_UNTIL_FULL | TraceLog::ENABLE_SAMPLING)); @@ -1606,7 +1632,8 @@ class MyData : public base::debug::ConvertableToTraceFormat { TEST_F(TraceEventTestFixture, ConvertableTypes) { ManualTestSetUp(); - TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); + TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"), + TraceLog::RECORD_UNTIL_FULL); scoped_ptr<MyData> data(new MyData()); TRACE_EVENT1("foo", "bar", "data", @@ -1667,9 +1694,10 @@ class TraceEventCallbackTest : public TraceEventTestFixture { TraceEventCallbackTest* TraceEventCallbackTest::s_instance; TEST_F(TraceEventCallbackTest, TraceEventCallback) { - TRACE_EVENT_INSTANT0("all", "before enable", TRACE_EVENT_SCOPE_GLOBAL); - TraceLog::GetInstance()->SetEnabled(true, TraceLog::RECORD_UNTIL_FULL); - TRACE_EVENT_INSTANT0("all", "before callback set", TRACE_EVENT_SCOPE_GLOBAL); + TRACE_EVENT_INSTANT0("all", "before enable", TRACE_EVENT_SCOPE_THREAD); + TraceLog::GetInstance()->SetEnabled(CategoryFilter("*"), + TraceLog::RECORD_UNTIL_FULL); + TRACE_EVENT_INSTANT0("all", "before callback set", TRACE_EVENT_SCOPE_THREAD); TraceLog::GetInstance()->SetEventCallback(Callback); TRACE_EVENT_INSTANT0("all", "event1", TRACE_EVENT_SCOPE_GLOBAL); TRACE_EVENT_INSTANT0("all", "event2", TRACE_EVENT_SCOPE_GLOBAL); @@ -1683,5 +1711,86 @@ TEST_F(TraceEventCallbackTest, TraceEventCallback) { // TODO(dsinclair): Continuous Tracing unit test. +// Test the category filter. +TEST_F(TraceEventTestFixture, CategoryFilter) { + ManualTestSetUp(); + + // Using the default filter. + CategoryFilter default_cf = CategoryFilter( + CategoryFilter::kDefaultCategoryFilterString); + std::string category_filter_str = default_cf.ToString(); + EXPECT_STREQ("-*Debug,-*Test", category_filter_str.c_str()); + EXPECT_TRUE(default_cf.IsCategoryGroupEnabled("not-excluded-category")); + EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("Category1,CategoryDebug")); + EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("CategoryDebug,Category1")); + EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("CategoryTest,Category2")); + + // Make sure that upon an empty string, we fall back to the default filter. + default_cf = CategoryFilter(""); + category_filter_str = default_cf.ToString(); + EXPECT_STREQ("-*Debug,-*Test", category_filter_str.c_str()); + EXPECT_TRUE(default_cf.IsCategoryGroupEnabled("not-excluded-category")); + EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("Category1,CategoryDebug")); + EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("CategoryDebug,Category1")); + EXPECT_FALSE(default_cf.IsCategoryGroupEnabled("CategoryTest,Category2")); + + // Using an arbitrary non-empty filter. + CategoryFilter cf("included,-excluded,inc_pattern*,-exc_pattern*"); + category_filter_str = cf.ToString(); + EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*", + category_filter_str.c_str()); + EXPECT_TRUE(cf.IsCategoryGroupEnabled("included")); + EXPECT_TRUE(cf.IsCategoryGroupEnabled("inc_pattern_category")); + EXPECT_FALSE(cf.IsCategoryGroupEnabled("exc_pattern_category")); + EXPECT_FALSE(cf.IsCategoryGroupEnabled("excluded")); + EXPECT_FALSE(cf.IsCategoryGroupEnabled("not-excluded-nor-included")); + EXPECT_FALSE(cf.IsCategoryGroupEnabled("Category1,CategoryDebug")); + EXPECT_FALSE(cf.IsCategoryGroupEnabled("CategoryDebug,Category1")); + EXPECT_FALSE(cf.IsCategoryGroupEnabled("CategoryTest,Category2")); + + cf.Merge(default_cf); + category_filter_str = cf.ToString(); + EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*,-*Debug,-*Test", + category_filter_str.c_str()); + cf.Clear(); + EXPECT_FALSE(cf.HasIncludedPatterns()); + + CategoryFilter reconstructed_cf(category_filter_str); + category_filter_str = reconstructed_cf.ToString(); + EXPECT_STREQ("included,inc_pattern*,-excluded,-exc_pattern*,-*Debug,-*Test", + category_filter_str.c_str()); + + // One included category. + CategoryFilter one_inc_cf("only_inc_cat"); + category_filter_str = one_inc_cf.ToString(); + EXPECT_STREQ("only_inc_cat", category_filter_str.c_str()); + + // One excluded category. + CategoryFilter one_exc_cf("-only_exc_cat"); + category_filter_str = one_exc_cf.ToString(); + EXPECT_STREQ("-only_exc_cat", category_filter_str.c_str()); + + // Test that IsEmptyOrContainsLeadingOrTrailingWhitespace actually catches + // categories that are explicitly forbiden. + // This method is called in a DCHECK to assert that we don't have these types + // of strings as categories. + EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( + " bad_category ")); + EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( + " bad_category")); + EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( + "bad_category ")); + EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( + " bad_category")); + EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( + "bad_category ")); + EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( + " bad_category ")); + EXPECT_TRUE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( + "")); + EXPECT_FALSE(CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( + "good_category")); +} + } // namespace debug } // namespace base diff --git a/base/test/trace_event_analyzer_unittest.cc b/base/test/trace_event_analyzer_unittest.cc index 52926fd..1e96bab 100644 --- a/base/test/trace_event_analyzer_unittest.cc +++ b/base/test/trace_event_analyzer_unittest.cc @@ -40,14 +40,12 @@ void TraceEventAnalyzerTest::BeginTracing() { output_.json_output.clear(); buffer_.Start(); base::debug::TraceLog::GetInstance()->SetEnabled( - true, + base::debug::CategoryFilter("*"), base::debug::TraceLog::RECORD_UNTIL_FULL); } void TraceEventAnalyzerTest::EndTracing() { - base::debug::TraceLog::GetInstance()->SetEnabled( - false, - base::debug::TraceLog::RECORD_UNTIL_FULL); + base::debug::TraceLog::GetInstance()->SetDisabled(); base::debug::TraceLog::GetInstance()->Flush( base::Bind(&TraceEventAnalyzerTest::OnTraceDataCollected, base::Unretained(this))); |