diff options
Diffstat (limited to 'base/debug/trace_event.h')
-rw-r--r-- | base/debug/trace_event.h | 464 |
1 files changed, 79 insertions, 385 deletions
diff --git a/base/debug/trace_event.h b/base/debug/trace_event.h index a1fff3e..21d1b32 100644 --- a/base/debug/trace_event.h +++ b/base/debug/trace_event.h @@ -2,6 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// This header is designed to give you trace_event macros without specifying +// how the events actually get collected and stored. If you need to expose trace +// event to some other universe, you can copy-and-paste this file, +// implement the TRACE_EVENT_API macros, and do any other necessary fixup for +// the target platform. The end result is that multiple libraries can funnel +// events through to a shared trace event collector. + // Trace events are for tracking application performance and resource usage. // Macros are provided to track: // Begin and end of function calls @@ -147,87 +154,16 @@ #define BASE_DEBUG_TRACE_EVENT_H_ #pragma once -#include "build/build_config.h" - #include <string> -#include <vector> - -#include "base/callback.h" -#include "base/hash_tables.h" -#include "base/memory/ref_counted_memory.h" -#include "base/string_util.h" -#include "base/synchronization/lock.h" -#include "base/third_party/dynamic_annotations/dynamic_annotations.h" -#include "base/timer.h" -//////////////////////////////////////////////////////////////////////////////// -// TODO(jbates): split this into a separate header. -// This header is designed to be give you trace_event macros without specifying -// how the events actually get collected and stored. If you need to expose trace -// event to some other universe, you can copy-and-paste this file and just -// implement these API macros. - -// unsigned char* -// TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name) -#define TRACE_EVENT_API_GET_CATEGORY_ENABLED \ - base::debug::TraceLog::GetCategoryEnabled - -// Returns the threshold_begin_id used by TRACE_IF_LONGER_THAN macros. -// int TRACE_EVENT_API_ADD_TRACE_EVENT( -// char phase, -// const unsigned char* category_enabled, -// const char* name, -// unsigned long long id, -// int num_args, -// const char** arg_names, -// const unsigned char* arg_types, -// const unsigned long long* arg_values, -// int threshold_begin_id, -// long long threshold, -// unsigned char flags) -#define TRACE_EVENT_API_ADD_TRACE_EVENT \ - base::debug::TraceLog::GetInstance()->AddTraceEvent - -// void TRACE_EVENT_API_ADD_COUNTER_EVENT( -// const unsigned char* category_enabled, -// const char* name, -// unsigned long long id, -// const char* arg1_name, int arg1_val, -// const char* arg2_name, int arg2_val, -// unsigned char flags) -#define TRACE_EVENT_API_ADD_COUNTER_EVENT \ - base::debug::TraceLog::GetInstance()->AddCounterEvent - -// Mangle |pointer| with a process ID hash so that if |pointer| occurs on more -// than one process, it will not collide in the trace data. -// unsigned long long TRACE_EVENT_API_GET_ID_FROM_POINTER(void* pointer) -#define TRACE_EVENT_API_GET_ID_FROM_POINTER \ - base::debug::TraceLog::GetInstance()->GetInterProcessID - -//////////////////////////////////////////////////////////////////////////////// +#include "build/build_config.h" +#include "base/debug/trace_event_impl.h" // By default, const char* argument values are assumed to have long-lived scope // and will not be copied. Use this macro to force a const char* to be copied. #define TRACE_STR_COPY(str) \ trace_event_internal::TraceStringWithCopy(str) -// Older style trace macros with explicit id and extra data -// Only these macros result in publishing data to ETW as currently implemented. -#define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ - base::debug::TraceLog::AddTraceEventEtw( \ - TRACE_EVENT_PHASE_BEGIN, \ - name, reinterpret_cast<const void*>(id), extra) - -#define TRACE_EVENT_END_ETW(name, id, extra) \ - base::debug::TraceLog::AddTraceEventEtw( \ - TRACE_EVENT_PHASE_END, \ - name, reinterpret_cast<const void*>(id), extra) - -#define TRACE_EVENT_INSTANT_ETW(name, id, extra) \ - base::debug::TraceLog::AddTraceEventEtw( \ - TRACE_EVENT_PHASE_INSTANT, \ - name, reinterpret_cast<const void*>(id), extra) - // Records a pair of begin and end events called "name" for the current // scope, with 0, 1 or 2 associated arguments. If the category is not // enabled, then this does nothing. @@ -377,9 +313,13 @@ // - category and name strings must have application lifetime (statics or // literals). They may not include " chars. #define TRACE_COUNTER1(category, name, value) \ - TRACE_COUNTER2(category, name, "value", value, NULL, 0) + INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ + category, name, TRACE_EVENT_FLAG_NONE, \ + "value", static_cast<int>(value)) #define TRACE_COPY_COUNTER1(category, name, value) \ - TRACE_COPY_COUNTER2(category, name, "value", value, NULL, 0) + INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ + category, name, TRACE_EVENT_FLAG_COPY, \ + "value", static_cast<int>(value)) // Records the values of a multi-parted counter called "name" immediately. // The UI will treat value1 and value2 as parts of a whole, displaying their @@ -388,16 +328,16 @@ // literals). They may not include " chars. #define TRACE_COUNTER2(category, name, value1_name, value1_val, \ value2_name, value2_val) \ - INTERNAL_TRACE_EVENT_ADD_COUNTER( \ - category, name, trace_event_internal::kNoEventId, \ - value1_name, value1_val, value2_name, value2_val, \ - TRACE_EVENT_FLAG_NONE) + INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ + category, 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, \ value2_name, value2_val) \ - INTERNAL_TRACE_EVENT_ADD_COUNTER( \ - category, name, trace_event_internal::kNoEventId, \ - value1_name, value1_val, value2_name, value2_val, \ - TRACE_EVENT_FLAG_COPY) + INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ + category, name, TRACE_EVENT_FLAG_COPY, \ + value1_name, static_cast<int>(value1_val), \ + value2_name, static_cast<int>(value2_val)) // Records the value of a counter called "name" immediately. Value // must be representable as a 32 bit integer. @@ -408,9 +348,13 @@ // 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) \ - TRACE_COUNTER_ID2(category, name, id, "value", value, NULL, 0) + INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ + category, name, id, TRACE_EVENT_FLAG_HAS_ID, \ + "value", static_cast<int>(value)) #define TRACE_COPY_COUNTER_ID1(category, name, id, value) \ - TRACE_COPY_COUNTER_ID2(category, name, id, "value", value, NULL, 0) + INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ + category, name, id, TRACE_EVENT_FLAG_COPY | TRACE_EVENT_FLAG_HAS_ID, \ + "value", static_cast<int>(value)) // Records the values of a multi-parted counter called "name" immediately. // The UI will treat value1 and value2 as parts of a whole, displaying their @@ -423,16 +367,16 @@ // two different processes will not collide. #define TRACE_COUNTER_ID2(category, name, id, value1_name, value1_val, \ value2_name, value2_val) \ - INTERNAL_TRACE_EVENT_ADD_COUNTER( \ - category, name, id, value1_name, value1_val, value2_name, value2_val, \ - TRACE_EVENT_FLAG_HAS_ID) + INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ + category, name, id, TRACE_EVENT_FLAG_HAS_ID, \ + 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) \ - INTERNAL_TRACE_EVENT_ADD_COUNTER( \ - category, name, id, \ - value1_name, value1_val, \ - value2_name, value2_val, \ - TRACE_EVENT_FLAG_COPY|TRACE_EVENT_FLAG_HAS_ID) + INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ + category, name, id, TRACE_EVENT_FLAG_COPY | TRACE_EVENT_FLAG_HAS_ID, \ + value1_name, static_cast<int>(value1_val), \ + value2_name, static_cast<int>(value2_val)) // Records a single START event called "name" immediately, with 0, 1 or 2 @@ -495,6 +439,48 @@ arg1_name, arg1_val, arg2_name, arg2_val) +//////////////////////////////////////////////////////////////////////////////// +// Implementation specific tracing API definitions. + +// const unsigned char* +// TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name) +#define TRACE_EVENT_API_GET_CATEGORY_ENABLED \ + base::debug::TraceLog::GetCategoryEnabled + +// Returns the threshold_begin_id used by TRACE_IF_LONGER_THAN macros. +// int TRACE_EVENT_API_ADD_TRACE_EVENT( +// char phase, +// const unsigned char* category_enabled, +// const char* name, +// unsigned long long id, +// int num_args, +// const char** arg_names, +// const unsigned char* arg_types, +// const unsigned long long* arg_values, +// int threshold_begin_id, +// long long threshold, +// unsigned char flags) +#define TRACE_EVENT_API_ADD_TRACE_EVENT \ + base::debug::TraceLog::GetInstance()->AddTraceEvent + +// void TRACE_EVENT_API_ADD_COUNTER_EVENT( +// const unsigned char* category_enabled, +// const char* name, +// unsigned long long id, +// const char* arg1_name, int arg1_val, +// const char* arg2_name, int arg2_val, +// unsigned char flags) +#define TRACE_EVENT_API_ADD_COUNTER_EVENT \ + base::debug::TraceLog::GetInstance()->AddCounterEvent + +// Mangle |pointer| with a process ID hash so that if |pointer| occurs on more +// than one process, it will not collide in the trace data. +// unsigned long long TRACE_EVENT_API_GET_ID_FROM_POINTER(void* pointer) +#define TRACE_EVENT_API_GET_ID_FROM_POINTER \ + base::debug::TraceLog::GetInstance()->GetInterProcessID + +//////////////////////////////////////////////////////////////////////////////// + // Implementation detail: trace event macros create temporary variables // to keep instrumentation overhead low. These macros give each temporary // variable a unique name based on the line number to prevent name collissions. @@ -525,18 +511,6 @@ trace_event_internal::kNoEventId, flags, ##__VA_ARGS__); \ } -// Implementation detail: internal macro to create static category and -// add the counter event if it is enabled. -#define INTERNAL_TRACE_EVENT_ADD_COUNTER( \ - category, name, id, arg1_name, arg1_val, arg2_name, arg2_val, flags) \ - INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ - if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \ - TRACE_EVENT_API_ADD_COUNTER_EVENT( \ - INTERNAL_TRACE_EVENT_UID(catstatic), \ - name, trace_event_internal::TraceID(id).data(), \ - arg1_name, arg1_val, arg2_name, arg2_val, flags); \ - } - // 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. @@ -586,17 +560,6 @@ ##__VA_ARGS__); \ } -template <typename Type> -struct StaticMemorySingletonTraits; - -namespace base { - -class RefCountedString; - -namespace debug { - -const int kTraceMaxNumArgs = 2; - // Notes regarding the following definitions: // New values can be added and propagated to third party libraries, but existing // definitions must never be changed, because third party libraries may use old @@ -625,275 +588,6 @@ const int kTraceMaxNumArgs = 2; #define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6)) #define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7)) -// Output records are "Events" and can be obtained via the -// OutputCallback whenever the tracing system decides to flush. This -// can happen at any time, on any thread, or you can programatically -// force it to happen. -class BASE_EXPORT TraceEvent { - public: - union TraceValue { - bool as_bool; - unsigned long long as_uint; - long long as_int; - double as_double; - const void* as_pointer; - const char* as_string; - }; - - TraceEvent(); - TraceEvent(int thread_id, - TimeTicks timestamp, - char phase, - const unsigned char* category_enabled, - const char* name, - unsigned long long id, - int num_args, - const char** arg_names, - const unsigned char* arg_types, - const unsigned long long* arg_values, - unsigned char flags); - ~TraceEvent(); - - // Serialize event data to JSON - static void AppendEventsAsJSON(const std::vector<TraceEvent>& events, - size_t start, - size_t count, - std::string* out); - void AppendAsJSON(std::string* out) const; - - TimeTicks timestamp() const { return timestamp_; } - - // Exposed for unittesting: - - const base::RefCountedString* parameter_copy_storage() const { - return parameter_copy_storage_.get(); - } - - const char* name() const { return name_; } - - private: - // Note: these are ordered by size (largest first) for optimal packing. - TimeTicks timestamp_; - // id_ can be used to store phase-specific data. - unsigned long long id_; - TraceValue arg_values_[kTraceMaxNumArgs]; - const char* arg_names_[kTraceMaxNumArgs]; - const unsigned char* category_enabled_; - const char* name_; - scoped_refptr<base::RefCountedString> parameter_copy_storage_; - int thread_id_; - char phase_; - unsigned char flags_; - unsigned char arg_types_[kTraceMaxNumArgs]; -}; - - -// TraceResultBuffer collects and converts trace fragments returned by TraceLog -// to JSON output. -class BASE_EXPORT TraceResultBuffer { - public: - typedef base::Callback<void(const std::string&)> OutputCallback; - - // If you don't need to stream JSON chunks out efficiently, and just want to - // get a complete JSON string after calling Finish, use this struct to collect - // JSON trace output. - struct BASE_EXPORT SimpleOutput { - OutputCallback GetCallback(); - void Append(const std::string& json_string); - - // Do what you want with the json_output_ string after calling - // TraceResultBuffer::Finish. - std::string json_output; - }; - - TraceResultBuffer(); - ~TraceResultBuffer(); - - // Set callback. The callback will be called during Start with the initial - // JSON output and during AddFragment and Finish with following JSON output - // chunks. The callback target must live past the last calls to - // TraceResultBuffer::Start/AddFragment/Finish. - void SetOutputCallback(const OutputCallback& json_chunk_callback); - - // Start JSON output. This resets all internal state, so you can reuse - // the TraceResultBuffer by calling Start. - void Start(); - - // Call AddFragment 0 or more times to add trace fragments from TraceLog. - void AddFragment(const std::string& trace_fragment); - - // When all fragments have been added, call Finish to complete the JSON - // formatted output. - void Finish(); - - private: - OutputCallback output_callback_; - bool append_comma_; -}; - - -class BASE_EXPORT TraceLog { - public: - static TraceLog* GetInstance(); - - // 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); - - // |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); - - // 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); - - // Disable tracing for all categories. - void SetDisabled(); - // Helper method to enable/disable tracing for all categories. - void SetEnabled(bool enabled); - bool IsEnabled() { return enabled_; } - - float GetBufferPercentFull() const; - - // When enough events are collected, they are handed (in bulk) to - // the output callback. If no callback is set, the output will be - // silently dropped. The callback must be thread safe. The string format is - // undefined. Use TraceResultBuffer to convert one or more trace strings to - // JSON. - typedef RefCountedData<std::string> RefCountedString; - typedef base::Callback<void(const scoped_refptr<RefCountedString>&)> - OutputCallback; - void SetOutputCallback(const OutputCallback& cb); - - // The trace buffer does not flush dynamically, so when it fills up, - // subsequent trace events will be dropped. This callback is generated when - // the trace buffer is full. The callback must be thread safe. - typedef base::Callback<void(void)> BufferFullCallback; - void SetBufferFullCallback(const BufferFullCallback& cb); - - // Flushes all logged data to the callback. - void Flush(); - - // 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); - - // Called by TRACE_EVENT* macros, don't call this directly. - // Returns the index in the internal vector of the event if it was added, or - // -1 if the event was not added. - // On end events, the return value of the begin event can be specified along - // with a threshold in microseconds. If the elapsed time between begin and end - // is less than the threshold, the begin/end event pair is dropped. - // 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. - int AddTraceEvent(char phase, - const unsigned char* category_enabled, - const char* name, - unsigned long long id, - int num_args, - const char** arg_names, - const unsigned char* arg_types, - const unsigned long long* arg_values, - int threshold_begin_id, - long long threshold, - unsigned char flags); - static void AddTraceEventEtw(char phase, - const char* name, - const void* id, - const char* extra); - static void AddTraceEventEtw(char phase, - const char* name, - const void* id, - const std::string& extra); - - // A wrapper around AddTraceEvent used by TRACE_COUNTERx macros - // that allows only integer values for the counters. - void AddCounterEvent(const unsigned char* category_enabled, - const char* name, - unsigned long long id, - const char* arg1_name, int arg1_val, - const char* arg2_name, int arg2_val, - unsigned char flags); - - // Mangle |ptr| with a hash based on the process ID so that if |ptr| occurs on - // more than one process, it will not collide. - unsigned long long GetInterProcessID(void* ptr) const { - return static_cast<unsigned long long>(reinterpret_cast<uintptr_t>(ptr)) ^ - process_id_hash_; - } - - int process_id() const { return process_id_; } - - // Exposed for unittesting: - - // Allows deleting our singleton instance. - static void DeleteForTesting(); - - // Allows resurrecting our singleton instance post-AtExit processing. - static void Resurrect(); - - // Allow tests to inspect TraceEvents. - size_t GetEventsSize() const { return logged_events_.size(); } - const TraceEvent& GetEventAt(size_t index) const { - DCHECK(index < logged_events_.size()); - return logged_events_[index]; - } - - void SetProcessID(int process_id); - - private: - // This allows constructor and destructor to be private and usable only - // by the Singleton class. - friend struct StaticMemorySingletonTraits<TraceLog>; - - TraceLog(); - ~TraceLog(); - const unsigned char* GetCategoryEnabledInternal(const char* name); - void AddThreadNameMetadataEvents(); - void AddClockSyncMetadataEvents(); - - // TODO(nduca): switch to per-thread trace buffers to reduce thread - // synchronization. - Lock lock_; - bool enabled_; - OutputCallback output_callback_; - BufferFullCallback buffer_full_callback_; - std::vector<TraceEvent> logged_events_; - std::vector<std::string> included_categories_; - std::vector<std::string> excluded_categories_; - - base::hash_map<int, std::string> thread_names_; - - // XORed with TraceID to make it unlikely to collide with other processes. - unsigned long long process_id_hash_; - - int process_id_; - - DISALLOW_COPY_AND_ASSIGN(TraceLog); -}; - -} // namespace debug -} // namespace base - namespace trace_event_internal { // Specify these values when the corresponding argument of AddTraceEvent is not |