trace_event_impl.h revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_DEBUG_TRACE_EVENT_IMPL_H_ 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <stack> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/hash_tables.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_vector.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/observer_list.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/condition_variable.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/timer.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Older style trace macros with explicit id and extra data 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Only these macros result in publishing data to ETW as currently implemented. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::debug::TraceLog::AddTraceEventEtw( \ 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_PHASE_BEGIN, \ 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name, reinterpret_cast<const void*>(id), extra) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_EVENT_END_ETW(name, id, extra) \ 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::debug::TraceLog::AddTraceEventEtw( \ 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_PHASE_END, \ 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name, reinterpret_cast<const void*>(id), extra) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_EVENT_INSTANT_ETW(name, id, extra) \ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::debug::TraceLog::AddTraceEventEtw( \ 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_PHASE_INSTANT, \ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name, reinterpret_cast<const void*>(id), extra) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type> 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct StaticMemorySingletonTraits; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WaitableEvent; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace debug { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// class must implement this interface. 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ConvertableToTraceFormat { 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~ConvertableToTraceFormat() {} 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Append the class info to the provided |out| string. The appended 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // data must be a valid JSON object. Strings must be propertly quoted, and 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // escaped. There is no processing applied to the content after it is 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // appended. 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void AppendAsTraceFormat(std::string* out) const = 0; 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTraceMaxNumArgs = 2; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Output records are "Events" and can be obtained via the 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OutputCallback whenever the tracing system decides to flush. This 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can happen at any time, on any thread, or you can programatically 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// force it to happen. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceEvent { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union TraceValue { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool as_bool; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long as_uint; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long long as_int; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double as_double; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* as_pointer; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* as_string; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceEvent(); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceEvent(int thread_id, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks timestamp, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char phase, 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long id, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_args, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char** arg_names, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char* arg_types, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned long long* arg_values, 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ConvertableToTraceFormat> convertable_values[], 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char flags); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TraceEvent(const TraceEvent& other); 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TraceEvent& operator=(const TraceEvent& other); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~TraceEvent(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Serialize event data to JSON 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AppendEventsAsJSON(const std::vector<TraceEvent>& events, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t start, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t count, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* out); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AppendAsJSON(std::string* out) const; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AppendValueAsJSON(unsigned char type, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceValue value, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* out); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks timestamp() const { return timestamp_; } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Exposed for unittesting: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::RefCountedString* parameter_copy_storage() const { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return parameter_copy_storage_.get(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled() const { 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return category_group_enabled_; 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name() const { return name_; } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: these are ordered by size (largest first) for optimal packing. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks timestamp_; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // id_ can be used to store phase-specific data. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long id_; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceValue arg_values_[kTraceMaxNumArgs]; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* arg_names_[kTraceMaxNumArgs]; 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ConvertableToTraceFormat> convertable_values_[kTraceMaxNumArgs]; 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled_; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name_; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::RefCountedString> parameter_copy_storage_; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int thread_id_; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char phase_; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char flags_; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char arg_types_[kTraceMaxNumArgs]; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TraceBuffer holds the events as they are collected. 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BASE_EXPORT TraceBuffer { 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~TraceBuffer() {} 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void AddEvent(const TraceEvent& event) = 0; 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool HasMoreEvents() const = 0; 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual const TraceEvent& NextEvent() = 0; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool IsFull() const = 0; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual size_t CountEnabledByName(const unsigned char* category, 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& event_name) const = 0; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual size_t Size() const = 0; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual const TraceEvent& GetEventAt(size_t index) const = 0; 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TraceResultBuffer collects and converts trace fragments returned by TraceLog 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to JSON output. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceResultBuffer { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<void(const std::string&)> OutputCallback; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If you don't need to stream JSON chunks out efficiently, and just want to 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // get a complete JSON string after calling Finish, use this struct to collect 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // JSON trace output. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct BASE_EXPORT SimpleOutput { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OutputCallback GetCallback(); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Append(const std::string& json_string); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do what you want with the json_output_ string after calling 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TraceResultBuffer::Finish. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string json_output; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceResultBuffer(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~TraceResultBuffer(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set callback. The callback will be called during Start with the initial 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // JSON output and during AddFragment and Finish with following JSON output 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // chunks. The callback target must live past the last calls to 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TraceResultBuffer::Start/AddFragment/Finish. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetOutputCallback(const OutputCallback& json_chunk_callback); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start JSON output. This resets all internal state, so you can reuse 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the TraceResultBuffer by calling Start. 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Start(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call AddFragment 0 or more times to add trace fragments from TraceLog. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddFragment(const std::string& trace_fragment); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When all fragments have been added, call Finish to complete the JSON 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // formatted output. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Finish(); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OutputCallback output_callback_; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool append_comma_; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class BASE_EXPORT CategoryFilter { 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The default category filter, used when none is provided. 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Allows all categories through, except if they end in the suffix 'Debug' or 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 'Test'. 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static const char* kDefaultCategoryFilterString; 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |filter_string| is a comma-delimited list of category wildcards. 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // A category can have an optional '-' prefix to make it an excluded category. 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // All the same rules apply above, so for example, having both included and 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // excluded categories in the same list would not be supported. 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter"test_MyTest*"); 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter("test_MyTest*,test_OtherStuff"); 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter("-excluded_category1,-excluded_category2"); 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter("-*,webkit"); would disable everything but webkit. 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Example: CategoryFilter("-webkit"); would enable everything but webkit. 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) explicit CategoryFilter(const std::string& filter_string); 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CategoryFilter(const CategoryFilter& cf); 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~CategoryFilter(); 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CategoryFilter& operator=(const CategoryFilter& rhs); 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Writes the string representation of the CategoryFilter. This is a comma 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // separated string, similar in nature to the one used to determine 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // enabled/disabled category patterns, except here there is an arbitrary 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // order, included categories go first, then excluded categories. Excluded 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // categories are distinguished from included categories by the prefix '-'. 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string ToString() const; 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Determines whether category group would be enabled or 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // disabled by this category filter. 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool IsCategoryGroupEnabled(const char* category_group) const; 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Merges nested_filter with the current CategoryFilter 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Merge(const CategoryFilter& nested_filter); 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Determines whether or not we have explicitly allowed category patterns. 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool HasIncludedPatterns() const; 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Clears both included/excluded pattern lists. This would be equivalent to 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // creating a CategoryFilter with an empty string, through the constructor. 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // i.e: CategoryFilter(""). 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // When using an empty filter, all categories are considered included as we 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // are not excluding anything. 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Clear(); 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static bool IsEmptyOrContainsLeadingOrTrailingWhitespace( 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& str); 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Initialize(const std::string& filter_string); 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void WriteString(std::string* out, bool included) const; 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<std::string> included_; 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<std::string> excluded_; 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TraceSamplingThread; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT TraceLog { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notification is a mask of one or more of the following events. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Notification { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The trace buffer does not flush dynamically, so when it fills up, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subsequent trace events will be dropped. This callback is generated when 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the trace buffer is full. The callback must be thread safe. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_BUFFER_FULL = 1 << 0, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A subscribed trace-event occurred. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVENT_WATCH_NOTIFICATION = 1 << 1 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Options determines how the trace buffer stores data. 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum Options { 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Record until the trace buffer is full. 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RECORD_UNTIL_FULL = 1 << 0, 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Record until the user ends the trace. The trace buffer is a fixed size 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and we use it as a ring buffer during recording. 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RECORD_CONTINUOUSLY = 1 << 1, 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Enable the sampling profiler. 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ENABLE_SAMPLING = 1 << 2, 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Echo to VLOG. Events are discared. 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ECHO_TO_VLOG = 1 << 3 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static TraceLog* GetInstance(); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the string does not provide valid options. 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static Options TraceOptionsFromString(const std::string& str); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get set of known category groups. This can change as new code paths are 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // reached. The known category groups are inserted into |category_groups|. 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void GetKnownCategoryGroups(std::vector<std::string>* category_groups); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Retrieves the current CategoryFilter. 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const CategoryFilter& GetCurrentCategoryFilter(); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Options trace_options() const { return trace_options_; } 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Enables tracing. See CategoryFilter comments for details 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // on how to control what categories will be traced. 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void SetEnabled(const CategoryFilter& category_filter, Options options); 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disable tracing for all categories. 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetDisabled(); 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool IsEnabled() { return !!enable_count_; } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void StartATrace(); 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void StopATrace(); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enabled state listeners give a callback when tracing is enabled or 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disabled. This can be used to tie into other library's tracing systems 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on-demand. 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class EnabledStateChangedObserver { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called just before the tracing system becomes 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // enabled. TraceLog::IsEnabled will return false at this point and trace 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // macros and methods called within the observer will deadlock. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnTraceLogWillEnable() { } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called just before the tracing system disables. TraceLog::IsEnabled is 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // still false at this point TRACE macros will still be capturing 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // data. However, trace macros and methods called within the observer will 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // deadlock. 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnTraceLogWillDisable() { } 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddEnabledStateObserver(EnabledStateChangedObserver* listener); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveEnabledStateObserver(EnabledStateChangedObserver* listener); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float GetBufferPercentFull() const; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the thread-safe notification callback. The callback can occur at any 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // time and from any thread. WARNING: It is possible for the previously set 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callback to be called during OR AFTER a call to SetNotificationCallback. 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Therefore, the target of the callback must either be a global function, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ref-counted object or a LazyInstance with Leaky traits (or equivalent). 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<void(int)> NotificationCallback; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetNotificationCallback(const NotificationCallback& cb); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Not using base::Callback because of its limited by 7 parameteters. 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Also, using primitive type allows directly passsing callback from WebCore. 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // WARNING: It is possible for the previously set callback to be called 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // after a call to SetEventCallback() that replaces or clears the callback. 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This callback may be invoked on any thread. 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef void (*EventCallback)(char phase, 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled, 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* name, 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned long long id, 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_args, 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* const arg_names[], 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned char arg_types[], 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned long long arg_values[], 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char flags); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetEventCallback(EventCallback cb); 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flush all collected events to the given output callback. The callback will 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be called one or more times with IPC-bite-size chunks. The string format is 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // undefined. Use TraceResultBuffer to convert one or more trace strings to 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // JSON. 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)> 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OutputCallback; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Flush(const OutputCallback& cb); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by TRACE_EVENT* macros, don't call this directly. 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The name parameter is a category group for example: 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static const unsigned char* GetCategoryGroupEnabled(const char* name); 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static const char* GetCategoryGroupName( 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by TRACE_EVENT* macros, don't call this directly. 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above. 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AddTraceEvent(char phase, 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled, 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* category_group, 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned long long id, 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_args, 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char** arg_names, 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned char* arg_types, 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned long long* arg_values, 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ConvertableToTraceFormat> convertable_values[], 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char flags); 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AddTraceEventWithThreadIdAndTimestamp( 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char phase, 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled, 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* name, 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned long long id, 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int thread_id, 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const TimeTicks& timestamp, 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_args, 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char** arg_names, 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned char* arg_types, 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned long long* arg_values, 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ConvertableToTraceFormat> convertable_values[], 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char flags); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AddTraceEventEtw(char phase, 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* category_group, 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* id, 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* extra); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AddTraceEventEtw(char phase, 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* category_group, 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* id, 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extra); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For every matching event, a notification will be fired. NOTE: the 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notification will fire for each matching event that has already occurred 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // since tracing was started (including before tracing if the process was 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // started with tracing turned on). 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetWatchEvent(const std::string& category_name, 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel the watch event. If tracing is enabled, this may race with the 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // watch event notification firing. 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CancelWatchEvent(); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int process_id() const { return process_id_; } 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Exposed for unittesting: 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void InstallWaitableEventForSamplingTesting(WaitableEvent* waitable_event); 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allows deleting our singleton instance. 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void DeleteForTesting(); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allows resurrecting our singleton instance post-AtExit processing. 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void Resurrect(); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allow tests to inspect TraceEvents. 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t GetEventsSize() const { return logged_events_->Size(); } 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TraceEvent& GetEventAt(size_t index) const { 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return logged_events_->GetEventAt(index); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetProcessID(int process_id); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Allow setting an offset between the current TimeTicks time and the time 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that should be reported. 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetTimeOffset(TimeDelta offset); 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This allows constructor and destructor to be private and usable only 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by the Singleton class. 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct StaticMemorySingletonTraits<TraceLog>; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Enable/disable each category group based on the current category_filter_. 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If the category group contains a category that matches an included category 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // pattern, that category group will be enabled. 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void EnableIncludedCategoryGroups(); 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void EnableIncludedCategoryGroup(int category_index); 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The pointer returned from GetCategoryGroupEnabledInternal() points to a 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // value with zero or more of the following bits. Used in this class only. 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The TRACE_EVENT macros should only use the value as a bool. 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum CategoryEnabledFlags { 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Normal enabled flag for categories enabled with Enable(). 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CATEGORY_ENABLED = 1 << 0, 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // On Android if ATrace is enabled, all categories will have this bit. 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Not used on other platforms. 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ATRACE_ENABLED = 1 << 1 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper class for managing notification_thread_count_ and running 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notification callbacks. This is very similar to a reader-writer lock, but 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shares the lock with TraceLog and manages the notification flags. 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class NotificationHelper { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline explicit NotificationHelper(TraceLog* trace_log); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline ~NotificationHelper(); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called only while TraceLog::lock_ is held. This ORs the given 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notification with any existing notifcations. 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void AddNotificationWhileLocked(int notification); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called only while TraceLog::lock_ is NOT held. If there are any pending 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notifications from previous calls to AddNotificationWhileLocked, this 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will call the NotificationCallback. 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void SendNotificationIfAny(); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceLog* trace_log_; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotificationCallback callback_copy_; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int notification_; 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceLog(); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~TraceLog(); 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* GetCategoryGroupEnabledInternal(const char* name); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddThreadNameMetadataEvents(); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SendToATrace(char phase, 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* category_group, 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name, 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned long long id, 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_args, 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char** arg_names, 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char* arg_types, 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned long long* arg_values, 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char flags); 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TraceBuffer* GetTraceBuffer(); 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(nduca): switch to per-thread trace buffers to reduce thread 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // synchronization. 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This lock protects TraceLog member accesses from arbitrary threads. 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Lock lock_; 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int enable_count_; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotificationCallback notification_callback_; 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<TraceBuffer> logged_events_; 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EventCallback event_callback_; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool dispatching_to_observer_list_; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObserverList<EnabledStateChangedObserver> enabled_state_observer_list_; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::hash_map<int, std::string> thread_names_; 522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; 523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::hash_map<std::string, int> thread_colors_; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // XORed with TraceID to make it unlikely to collide with other processes. 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long process_id_hash_; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int process_id_; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TimeDelta time_offset_; 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allow tests to wake up when certain events occur. 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char* watch_category_; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string watch_event_name_; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Options trace_options_; 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sampling thread handles. 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<TraceSamplingThread> sampling_thread_; 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PlatformThreadHandle sampling_thread_handle_; 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CategoryFilter category_filter_; 543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TraceLog); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace debug 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ 551