| Index: base/debug/trace_event.cc
|
| diff --git a/base/debug/trace_event.cc b/base/debug/trace_event.cc
|
| index a7ea89d124e6a08beb4ee18b9186873d0633036c..5be1557403f17e5bdfc9300d255115c29cb136de 100644
|
| --- a/base/debug/trace_event.cc
|
| +++ b/base/debug/trace_event.cc
|
| @@ -43,6 +43,14 @@ const size_t kTraceEventBatchSize = 1000;
|
|
|
| namespace {
|
|
|
| +// Specify these values when the corresponding argument of AddTraceEvent is not
|
| +// used.
|
| +static const char* kNoArgName = NULL;
|
| +static const int kNoArgValue = 0;
|
| +static const int kNoThreshholdBeginId = -1;
|
| +static const int64 kNoThresholdValue = 0;
|
| +static const int kNoEventId = 0;
|
| +
|
| TraceCategory g_categories[TRACE_EVENT_MAX_CATEGORIES] = {
|
| { "tracing already shutdown", false },
|
| { "tracing categories exhausted; must increase TRACE_EVENT_MAX_CATEGORIES",
|
| @@ -72,32 +80,26 @@ LazyInstance<ThreadLocalPointer<const char>,
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|
| void TraceValue::AppendAsJSON(std::string* out) const {
|
| - char temp_string[128];
|
| std::string::size_type start_pos;
|
| switch (type_) {
|
| case TRACE_TYPE_BOOL:
|
| *out += as_bool() ? "true" : "false";
|
| break;
|
| case TRACE_TYPE_UINT:
|
| - base::snprintf(temp_string, arraysize(temp_string), "%llu",
|
| - static_cast<unsigned long long>(as_uint()));
|
| - *out += temp_string;
|
| + StringAppendF(out, "%" PRIu64, as_uint());
|
| break;
|
| case TRACE_TYPE_INT:
|
| - base::snprintf(temp_string, arraysize(temp_string), "%lld",
|
| - static_cast<long long>(as_int()));
|
| - *out += temp_string;
|
| + StringAppendF(out, "%" PRId64, as_int());
|
| break;
|
| case TRACE_TYPE_DOUBLE:
|
| - base::snprintf(temp_string, arraysize(temp_string), "%f", as_double());
|
| - *out += temp_string;
|
| + StringAppendF(out, "%f", as_double());
|
| break;
|
| case TRACE_TYPE_POINTER:
|
| - base::snprintf(temp_string, arraysize(temp_string), "%llu",
|
| - static_cast<unsigned long long>(
|
| - reinterpret_cast<intptr_t>(
|
| - as_pointer())));
|
| - *out += temp_string;
|
| + // JSON only supports double and int numbers.
|
| + // So as not to lose bits from a 64-bit pointer, output as a hex string.
|
| + StringAppendF(out, "\"%" PRIx64 "\"", static_cast<uint64>(
|
| + reinterpret_cast<intptr_t>(
|
| + as_pointer())));
|
| break;
|
| case TRACE_TYPE_STRING:
|
| case TRACE_TYPE_STATIC_STRING:
|
| @@ -121,6 +123,17 @@ void TraceValue::AppendAsJSON(std::string* out) const {
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| //
|
| +// TraceID
|
| +//
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +TraceID::TraceID(void* rhs) {
|
| + data_ = base::debug::TraceLog::GetInstance()->GetIntraProcessID(
|
| + static_cast<uint64>(reinterpret_cast<uintptr_t>(rhs)));
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +//
|
| // TraceEvent
|
| //
|
| ////////////////////////////////////////////////////////////////////////////////
|
| @@ -145,36 +158,39 @@ void CopyTraceEventParameter(char** buffer,
|
| } // namespace
|
|
|
| TraceEvent::TraceEvent()
|
| - : process_id_(0),
|
| + : id_(0u),
|
| + category_(NULL),
|
| + name_(NULL),
|
| thread_id_(0),
|
| phase_(TRACE_EVENT_PHASE_BEGIN),
|
| - category_(NULL),
|
| - name_(NULL) {
|
| + flags_(0) {
|
| arg_names_[0] = NULL;
|
| arg_names_[1] = NULL;
|
| }
|
|
|
| -TraceEvent::TraceEvent(unsigned long process_id,
|
| - unsigned long thread_id,
|
| +TraceEvent::TraceEvent(int thread_id,
|
| TimeTicks timestamp,
|
| TraceEventPhase phase,
|
| const TraceCategory* category,
|
| const char* name,
|
| + TraceID id,
|
| const char* arg1_name, const TraceValue& arg1_val,
|
| const char* arg2_name, const TraceValue& arg2_val,
|
| - bool copy)
|
| - : process_id_(process_id),
|
| + TraceEventFlags flags)
|
| + : timestamp_(timestamp),
|
| + id_(id),
|
| + category_(category),
|
| + name_(name),
|
| thread_id_(thread_id),
|
| - timestamp_(timestamp),
|
| phase_(phase),
|
| - category_(category),
|
| - name_(name) {
|
| + flags_(flags) {
|
| COMPILE_ASSERT(kTraceMaxNumArgs == 2, TraceEvent_arg_count_out_of_sync);
|
| arg_names_[0] = arg1_name;
|
| arg_names_[1] = arg2_name;
|
| arg_values_[0] = arg1_val;
|
| arg_values_[1] = arg2_val;
|
|
|
| + bool copy = !!(flags & TRACE_EVENT_FLAG_COPY);
|
| size_t alloc_size = 0;
|
| if (copy) {
|
| alloc_size += GetAllocLength(name);
|
| @@ -213,42 +229,6 @@ TraceEvent::TraceEvent(unsigned long process_id,
|
| TraceEvent::~TraceEvent() {
|
| }
|
|
|
| -const char* TraceEvent::GetPhaseString(TraceEventPhase phase) {
|
| - switch(phase) {
|
| - case TRACE_EVENT_PHASE_BEGIN:
|
| - return "B";
|
| - case TRACE_EVENT_PHASE_INSTANT:
|
| - return "I";
|
| - case TRACE_EVENT_PHASE_END:
|
| - return "E";
|
| - case TRACE_EVENT_PHASE_METADATA:
|
| - return "M";
|
| - case TRACE_EVENT_PHASE_COUNTER:
|
| - return "C";
|
| - default:
|
| - NOTREACHED() << "Invalid phase argument";
|
| - return "?";
|
| - }
|
| -}
|
| -
|
| -TraceEventPhase TraceEvent::GetPhase(const char* phase) {
|
| - switch(*phase) {
|
| - case 'B':
|
| - return TRACE_EVENT_PHASE_BEGIN;
|
| - case 'I':
|
| - return TRACE_EVENT_PHASE_INSTANT;
|
| - case 'E':
|
| - return TRACE_EVENT_PHASE_END;
|
| - case 'M':
|
| - return TRACE_EVENT_PHASE_METADATA;
|
| - case 'C':
|
| - return TRACE_EVENT_PHASE_COUNTER;
|
| - default:
|
| - NOTREACHED() << "Invalid phase name";
|
| - return TRACE_EVENT_PHASE_METADATA;
|
| - }
|
| -}
|
| -
|
| void TraceEvent::AppendEventsAsJSON(const std::vector<TraceEvent>& events,
|
| size_t start,
|
| size_t count,
|
| @@ -261,18 +241,19 @@ void TraceEvent::AppendEventsAsJSON(const std::vector<TraceEvent>& events,
|
| }
|
|
|
| void TraceEvent::AppendAsJSON(std::string* out) const {
|
| - const char* phase_str = GetPhaseString(phase_);
|
| + const char phase_char = GetPhaseChar(phase_);
|
| int64 time_int64 = timestamp_.ToInternalValue();
|
| + int process_id = TraceLog::GetInstance()->process_id();
|
| // Category name checked at category creation time.
|
| DCHECK(!strchr(name_, '"'));
|
| StringAppendF(out,
|
| - "{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%lld,"
|
| - "\"ph\":\"%s\",\"name\":\"%s\",\"args\":{",
|
| + "{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 ","
|
| + "\"ph\":\"%c\",\"name\":\"%s\",\"args\":{",
|
| category_->name,
|
| - static_cast<int>(process_id_),
|
| - static_cast<int>(thread_id_),
|
| - static_cast<long long>(time_int64),
|
| - phase_str,
|
| + process_id,
|
| + thread_id_,
|
| + time_int64,
|
| + phase_char,
|
| name_);
|
|
|
| // Output argument names and values, stop at first NULL argument name.
|
| @@ -284,7 +265,13 @@ void TraceEvent::AppendAsJSON(std::string* out) const {
|
| *out += "\":";
|
| arg_values_[i].AppendAsJSON(out);
|
| }
|
| - *out += "}}";
|
| + *out += "}";
|
| +
|
| + // If id_ is set, print it out as a hex string so we don't loose any
|
| + // bits (it might be a 64-bit pointer).
|
| + if (flags_ & TRACE_EVENT_FLAG_HAS_ID)
|
| + StringAppendF(out, ",\"id\":\"%" PRIx64 "\"", id_.data());
|
| + *out += "}";
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| @@ -342,6 +329,7 @@ TraceLog* TraceLog::GetInstance() {
|
|
|
| TraceLog::TraceLog()
|
| : enabled_(false) {
|
| + SetProcessID(static_cast<int>(base::GetCurrentProcId()));
|
| }
|
|
|
| TraceLog::~TraceLog() {
|
| @@ -533,11 +521,12 @@ void TraceLog::Flush() {
|
| int TraceLog::AddTraceEvent(TraceEventPhase phase,
|
| const TraceCategory* category,
|
| const char* name,
|
| + TraceID id,
|
| const char* arg1_name, TraceValue arg1_val,
|
| const char* arg2_name, TraceValue arg2_val,
|
| int threshold_begin_id,
|
| int64 threshold,
|
| - EventFlags flags) {
|
| + TraceEventFlags flags) {
|
| DCHECK(name);
|
| TimeTicks now = TimeTicks::HighResNow();
|
| BufferFullCallback buffer_full_callback_copy;
|
| @@ -549,7 +538,7 @@ int TraceLog::AddTraceEvent(TraceEventPhase phase,
|
| if (logged_events_.size() >= kTraceEventBufferSize)
|
| return -1;
|
|
|
| - PlatformThreadId thread_id = PlatformThread::CurrentId();
|
| + int thread_id = static_cast<int>(PlatformThread::CurrentId());
|
|
|
| const char* new_name = PlatformThread::GetName();
|
| // Check if the thread name has been set or changed since the previous
|
| @@ -559,7 +548,7 @@ int TraceLog::AddTraceEvent(TraceEventPhase phase,
|
| if (new_name != g_current_thread_name.Get().Get() &&
|
| new_name && *new_name) {
|
| g_current_thread_name.Get().Set(new_name);
|
| - base::hash_map<PlatformThreadId, std::string>::iterator existing_name =
|
| + base::hash_map<int, std::string>::iterator existing_name =
|
| thread_names_.find(thread_id);
|
| if (existing_name == thread_names_.end()) {
|
| // This is a new thread id, and a new name.
|
| @@ -580,7 +569,7 @@ int TraceLog::AddTraceEvent(TraceEventPhase phase,
|
| }
|
|
|
| if (threshold_begin_id > -1) {
|
| - DCHECK(phase == base::debug::TRACE_EVENT_PHASE_END);
|
| + DCHECK(phase == TRACE_EVENT_PHASE_END);
|
| size_t begin_i = static_cast<size_t>(threshold_begin_id);
|
| // Return now if there has been a flush since the begin event was posted.
|
| if (begin_i >= logged_events_.size())
|
| @@ -597,12 +586,11 @@ int TraceLog::AddTraceEvent(TraceEventPhase phase,
|
| }
|
| ret_begin_id = static_cast<int>(logged_events_.size());
|
| logged_events_.push_back(
|
| - TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()),
|
| - thread_id,
|
| - now, phase, category, name,
|
| + TraceEvent(thread_id,
|
| + now, phase, category, name, id,
|
| arg1_name, arg1_val,
|
| arg2_name, arg2_val,
|
| - flags & EVENT_FLAG_COPY));
|
| + flags));
|
|
|
| if (logged_events_.size() == kTraceEventBufferSize) {
|
| buffer_full_callback_copy = buffer_full_callback_;
|
| @@ -624,7 +612,7 @@ void TraceLog::AddTraceEventEtw(TraceEventPhase phase,
|
| #endif
|
| INTERNAL_TRACE_EVENT_ADD(phase,
|
| "ETW Trace Event", name, "id", id, "extra", TRACE_STR_COPY(extra),
|
| - base::debug::TraceLog::EVENT_FLAG_COPY);
|
| + TRACE_EVENT_FLAG_COPY);
|
| }
|
|
|
| void TraceLog::AddTraceEventEtw(TraceEventPhase phase,
|
| @@ -637,17 +625,18 @@ void TraceLog::AddTraceEventEtw(TraceEventPhase phase,
|
| #endif
|
| INTERNAL_TRACE_EVENT_ADD(phase,
|
| "ETW Trace Event", name, "id", id, "extra", extra,
|
| - base::debug::TraceLog::EVENT_FLAG_COPY);
|
| + TRACE_EVENT_FLAG_COPY);
|
| }
|
|
|
| int TraceLog::AddCounterEvent(const TraceCategory* category,
|
| const char* name,
|
| const char* value1_name, int32 value1_val,
|
| const char* value2_name, int32 value2_val,
|
| - EventFlags flags) {
|
| + TraceEventFlags flags) {
|
| return AddTraceEvent(TRACE_EVENT_PHASE_COUNTER,
|
| category,
|
| name,
|
| + 0,
|
| value1_name, value1_val,
|
| value2_name, value2_val,
|
| -1, 0,
|
| @@ -656,19 +645,17 @@ int TraceLog::AddCounterEvent(const TraceCategory* category,
|
|
|
| void TraceLog::AddCurrentMetadataEvents() {
|
| lock_.AssertAcquired();
|
| - for(base::hash_map<PlatformThreadId, std::string>::iterator it =
|
| - thread_names_.begin();
|
| + for(base::hash_map<int, std::string>::iterator it = thread_names_.begin();
|
| it != thread_names_.end();
|
| it++) {
|
| if (!it->second.empty())
|
| logged_events_.push_back(
|
| - TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()),
|
| - it->first,
|
| - TimeTicks(), base::debug::TRACE_EVENT_PHASE_METADATA,
|
| - g_category_metadata, "thread_name",
|
| + TraceEvent(it->first,
|
| + TimeTicks(), TRACE_EVENT_PHASE_METADATA,
|
| + g_category_metadata, "thread_name", 0,
|
| "name", it->second,
|
| NULL, 0,
|
| - false));
|
| + TRACE_EVENT_FLAG_NONE));
|
| }
|
| }
|
|
|
| @@ -680,6 +667,16 @@ void TraceLog::Resurrect() {
|
| StaticMemorySingletonTraits<TraceLog>::Resurrect();
|
| }
|
|
|
| +void TraceLog::SetProcessID(int process_id) {
|
| + process_id_ = process_id;
|
| + // Create a FNV hash from the process ID for XORing.
|
| + // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details.
|
| + uint64 offset_basis = 14695981039346656037ull;
|
| + uint64 fnv_prime = 1099511628211ull;
|
| + unsigned long long pid = static_cast<unsigned long long>(process_id_);
|
| + process_id_hash_ = (offset_basis ^ pid) * fnv_prime;
|
| +}
|
| +
|
| namespace internal {
|
|
|
| void TraceEndOnScopeClose::Initialize(const TraceCategory* category,
|
| @@ -693,11 +690,11 @@ void TraceEndOnScopeClose::AddEventIfEnabled() {
|
| // Only called when p_data_ is non-null.
|
| if (p_data_->category->enabled) {
|
| base::debug::TraceLog::GetInstance()->AddTraceEvent(
|
| - base::debug::TRACE_EVENT_PHASE_END,
|
| + TRACE_EVENT_PHASE_END,
|
| p_data_->category,
|
| - p_data_->name,
|
| - NULL, 0, NULL, 0,
|
| - -1, 0, TraceLog::EVENT_FLAG_NONE);
|
| + p_data_->name, kNoEventId,
|
| + kNoArgName, kNoArgValue, kNoArgName, kNoArgValue,
|
| + kNoThreshholdBeginId, kNoThresholdValue, TRACE_EVENT_FLAG_NONE);
|
| }
|
| }
|
|
|
| @@ -716,12 +713,12 @@ void TraceEndOnScopeCloseThreshold::AddEventIfEnabled() {
|
| // Only called when p_data_ is non-null.
|
| if (p_data_->category->enabled) {
|
| base::debug::TraceLog::GetInstance()->AddTraceEvent(
|
| - base::debug::TRACE_EVENT_PHASE_END,
|
| + TRACE_EVENT_PHASE_END,
|
| p_data_->category,
|
| - p_data_->name,
|
| - NULL, 0, NULL, 0,
|
| + p_data_->name, kNoEventId,
|
| + kNoArgName, kNoArgValue, kNoArgName, kNoArgValue,
|
| p_data_->threshold_begin_id, p_data_->threshold,
|
| - TraceLog::EVENT_FLAG_NONE);
|
| + TRACE_EVENT_FLAG_NONE);
|
| }
|
| }
|
|
|
|
|