Index: base/debug/trace_event.h |
diff --git a/base/debug/trace_event.h b/base/debug/trace_event.h |
index e581094c1a3657d53aafc18406a824739e9301ee..641b28087ca0a9e31a5d4fc368069d8857978c8c 100644 |
--- a/base/debug/trace_event.h |
+++ b/base/debug/trace_event.h |
@@ -34,6 +34,31 @@ |
// The trace system will automatically add to this information the |
// current process id, thread id, and a timestamp in microseconds. |
// |
+// BEGIN and END events should typically be used in the same scope. To trace |
nduca
2011/12/01 02:55:26
typically->clearly state the nesting requirement.
jbates
2011/12/01 23:07:50
Done.
|
+// an asynchronous procedure such as IPC send/receive, use START and FINISH: |
+// void* ipc_send(...) { |
+// static int send_count = 0; |
+// ++send_count; |
+// TRACE_EVENT_START0("ipc", "message", send_count); |
+// } |
+// void ipc_recv(...) { |
+// static int recv_count = 0; |
jar (doing other things)
2011/12/01 01:47:49
This is not multi-thread safe. At first, I though
nduca
2011/12/01 02:55:26
+1, even though its docs, it should be "legitimate
jbates
2011/12/01 23:07:50
Done.
|
+// ++recv_count; |
+// TRACE_EVENT_FINISH0("ipc", "message", send_count); |
+// } |
+// The third parameter is a unique ID to match START/FINISH pairs. |
+// START and FINISH can occur on any thread of any traced process. Pointers can |
+// be used for the ID parameter, and they will be mangled internally so that |
+// the same pointer on two different processes will not match. For example: |
+// void* trace_malloc(size) { |
+// void* ptr = malloc(size); |
+// TRACE_EVENT_START0("memory", "malloc", ptr); |
+// } |
+// void trace_free(ptr) { |
+// free(ptr); |
+// TRACE_EVENT_FINISH0("memory", "malloc", ptr); |
jar (doing other things)
2011/12/01 01:47:49
FYI: If you put the free after the event, then you
nduca
2011/12/01 02:55:26
I suggest using an example closer to that ReadTran
jbates
2011/12/01 23:07:50
Done.
|
+// } |
+// |
// Trace event also supports counters, which is a way to track a quantity |
// as it varies over time. Counters are created with the following macro: |
// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue); |
@@ -137,17 +162,17 @@ |
// Only these macros result in publishing data to ETW as currently implemented. |
#define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ |
base::debug::TraceLog::AddTraceEventEtw( \ |
- base::debug::TRACE_EVENT_PHASE_BEGIN, \ |
+ TRACE_EVENT_PHASE_BEGIN, \ |
name, reinterpret_cast<const void*>(id), extra) |
#define TRACE_EVENT_END_ETW(name, id, extra) \ |
base::debug::TraceLog::AddTraceEventEtw( \ |
- base::debug::TRACE_EVENT_PHASE_END, \ |
+ TRACE_EVENT_PHASE_END, \ |
name, reinterpret_cast<const void*>(id), extra) |
#define TRACE_EVENT_INSTANT_ETW(name, id, extra) \ |
base::debug::TraceLog::AddTraceEventEtw( \ |
- base::debug::TRACE_EVENT_PHASE_INSTANT, \ |
+ TRACE_EVENT_PHASE_INSTANT, \ |
name, reinterpret_cast<const void*>(id), extra) |
// Records a pair of begin and end events called "name" for the current |
@@ -190,20 +215,20 @@ |
TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, NULL, 0) |
#define TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \ |
arg2_name, arg2_val) \ |
- INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_INSTANT, \ |
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ |
category, name, arg1_name, arg1_val, arg2_name, arg2_val, \ |
- base::debug::TraceLog::EVENT_FLAG_NONE) |
+ TRACE_EVENT_FLAG_NONE) |
#define TRACE_EVENT_COPY_INSTANT0(category, name) \ |
TRACE_EVENT_COPY_INSTANT1(category, name, NULL, 0) |
#define TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val) \ |
TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, NULL, 0) |
#define TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, \ |
arg2_name, arg2_val) \ |
- INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_INSTANT, \ |
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ |
category, name, \ |
arg1_name, base::debug::TraceValue::ForceCopy(arg1_val), \ |
arg2_name, base::debug::TraceValue::ForceCopy(arg2_val), \ |
- base::debug::TraceLog::EVENT_FLAG_COPY) |
+ TRACE_EVENT_FLAG_COPY) |
// Records a single BEGIN event called "name" immediately, with 0, 1 or 2 |
// associated arguments. If the category is not enabled, then this |
@@ -216,20 +241,20 @@ |
TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, NULL, 0) |
#define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \ |
arg2_name, arg2_val) \ |
- INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_BEGIN, \ |
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ |
category, name, arg1_name, arg1_val, arg2_name, arg2_val, \ |
- base::debug::TraceLog::EVENT_FLAG_NONE) |
+ TRACE_EVENT_FLAG_NONE) |
#define TRACE_EVENT_COPY_BEGIN0(category, name) \ |
TRACE_EVENT_COPY_BEGIN1(category, name, NULL, 0) |
#define TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) \ |
TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, NULL, 0) |
#define TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \ |
arg2_name, arg2_val) \ |
- INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_BEGIN, \ |
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ |
category, name, \ |
arg1_name, base::debug::TraceValue::ForceCopy(arg1_val), \ |
arg2_name, base::debug::TraceValue::ForceCopy(arg2_val), \ |
- base::debug::TraceLog::EVENT_FLAG_COPY) |
+ TRACE_EVENT_FLAG_COPY) |
// Records a single END event for "name" immediately. If the category |
// is not enabled, then this does nothing. |
@@ -241,20 +266,20 @@ |
TRACE_EVENT_END2(category, name, arg1_name, arg1_val, NULL, 0) |
#define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \ |
arg2_name, arg2_val) \ |
- INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_END, \ |
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ |
category, name, arg1_name, arg1_val, arg2_name, arg2_val, \ |
- base::debug::TraceLog::EVENT_FLAG_NONE) |
+ TRACE_EVENT_FLAG_NONE) |
#define TRACE_EVENT_COPY_END0(category, name) \ |
TRACE_EVENT_COPY_END1(category, name, NULL, 0) |
#define TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) \ |
TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, NULL, 0) |
#define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \ |
arg2_name, arg2_val) \ |
- INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_END, \ |
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ |
category, name, \ |
arg1_name, base::debug::TraceValue::ForceCopy(arg1_val), \ |
arg2_name, base::debug::TraceValue::ForceCopy(arg2_val), \ |
- base::debug::TraceLog::EVENT_FLAG_COPY) |
+ TRACE_EVENT_FLAG_COPY) |
// Time threshold event: |
// Only record the event if the duration is greater than the specified |
@@ -293,14 +318,68 @@ |
value2_name, value2_val) \ |
INTERNAL_TRACE_EVENT_ADD_COUNTER( \ |
category, name, value1_name, value1_val, value2_name, value2_val, \ |
- base::debug::TraceLog::EVENT_FLAG_NONE) |
+ TRACE_EVENT_FLAG_NONE) |
#define TRACE_COPY_COUNTER2(category, name, value1_name, value1_val, \ |
value2_name, value2_val) \ |
INTERNAL_TRACE_EVENT_ADD_COUNTER( \ |
category, name, \ |
value1_name, value1_val, \ |
value2_name, value2_val, \ |
- base::debug::TraceLog::EVENT_FLAG_COPY) |
+ TRACE_EVENT_FLAG_COPY) |
+ |
+ |
+// Records a single START event called "name" immediately, with 0, 1 or 2 |
+// associated arguments. 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. |
+// - |id| is used to match the START event with the FINISH event. It 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_START0(category, name, id) \ |
+ TRACE_EVENT_START1(category, name, id, NULL, 0) |
+#define TRACE_EVENT_START1(category, name, id, arg1_name, arg1_val) \ |
+ TRACE_EVENT_START2(category, name, id, arg1_name, arg1_val, NULL, 0) |
+#define TRACE_EVENT_START2(category, name, id, arg1_name, arg1_val, \ |
+ arg2_name, arg2_val) \ |
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_START, \ |
+ category, name, id, arg1_name, arg1_val, arg2_name, arg2_val, \ |
+ TRACE_EVENT_FLAG_HAS_ID) |
+#define TRACE_EVENT_COPY_START0(category, name, id) \ |
+ TRACE_EVENT_COPY_START1(category, name, id, NULL, 0) |
+#define TRACE_EVENT_COPY_START1(category, name, id, arg1_name, arg1_val) \ |
+ TRACE_EVENT_COPY_START2(category, name, id, arg1_name, arg1_val, NULL, 0) |
+#define TRACE_EVENT_COPY_START2(category, name, id, arg1_name, arg1_val, \ |
+ arg2_name, arg2_val) \ |
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_START, \ |
+ category, name, id, \ |
+ arg1_name, base::debug::TraceValue::ForceCopy(arg1_val), \ |
+ arg2_name, base::debug::TraceValue::ForceCopy(arg2_val), \ |
+ TRACE_EVENT_FLAG_HAS_ID | TRACE_EVENT_FLAG_COPY) |
+ |
+// Records a single FINISH event for "name" immediately. If the category |
+// is not enabled, then this does nothing. |
+#define TRACE_EVENT_FINISH0(category, name, id) \ |
+ TRACE_EVENT_FINISH1(category, name, id, NULL, 0) |
+#define TRACE_EVENT_FINISH1(category, name, id, arg1_name, arg1_val) \ |
+ TRACE_EVENT_FINISH2(category, name, id, arg1_name, arg1_val, NULL, 0) |
+#define TRACE_EVENT_FINISH2(category, name, id, arg1_name, arg1_val, \ |
+ arg2_name, arg2_val) \ |
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FINISH, \ |
+ category, name, id, arg1_name, arg1_val, arg2_name, arg2_val, \ |
+ TRACE_EVENT_FLAG_HAS_ID) |
+#define TRACE_EVENT_COPY_FINISH0(category, name, id) \ |
+ TRACE_EVENT_COPY_FINISH1(category, name, id, NULL, 0) |
+#define TRACE_EVENT_COPY_FINISH1(category, name, id, arg1_name, arg1_val) \ |
+ TRACE_EVENT_COPY_FINISH2(category, name, id, arg1_name, arg1_val, NULL, 0) |
+#define TRACE_EVENT_COPY_FINISH2(category, name, id, arg1_name, arg1_val, \ |
+ arg2_name, arg2_val) \ |
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FINISH, \ |
+ category, name, id, \ |
+ arg1_name, base::debug::TraceValue::ForceCopy(arg1_val), \ |
+ arg2_name, base::debug::TraceValue::ForceCopy(arg2_val), \ |
+ TRACE_EVENT_FLAG_HAS_ID | TRACE_EVENT_FLAG_COPY) |
// Implementation detail: trace event macros create temporary variables |
@@ -324,7 +403,7 @@ |
INTERNAL_TRACE_EVENT_UID(catstatic) = \ |
base::debug::TraceLog::GetCategory(category); |
-// Implementation detail: internal macro to create static category and add begin |
+// Implementation detail: internal macro to create static category and add |
// event if the category is enabled. |
#define INTERNAL_TRACE_EVENT_ADD( \ |
phase, category, name, arg1_name, arg1_val, arg2_name, arg2_val, flags) \ |
@@ -332,7 +411,7 @@ |
if (INTERNAL_TRACE_EVENT_UID(catstatic)->enabled) { \ |
base::debug::TraceLog::GetInstance()->AddTraceEvent( \ |
phase, INTERNAL_TRACE_EVENT_UID(catstatic), \ |
- name, arg1_name, arg1_val, arg2_name, arg2_val, -1, 0, flags); \ |
+ name, 0, arg1_name, arg1_val, arg2_name, arg2_val, -1, 0, flags); \ |
} |
// Implementation detail: internal macro to create static category and |
@@ -356,10 +435,10 @@ |
INTERNAL_TRACE_EVENT_UID(profileScope); \ |
if (INTERNAL_TRACE_EVENT_UID(catstatic)->enabled) { \ |
base::debug::TraceLog::GetInstance()->AddTraceEvent( \ |
- base::debug::TRACE_EVENT_PHASE_BEGIN, \ |
+ TRACE_EVENT_PHASE_BEGIN, \ |
INTERNAL_TRACE_EVENT_UID(catstatic), \ |
- name, arg1_name, arg1_val, arg2_name, arg2_val, -1, 0, \ |
- base::debug::TraceLog::EVENT_FLAG_NONE); \ |
+ name, 0, arg1_name, arg1_val, arg2_name, arg2_val, -1, 0, \ |
+ TRACE_EVENT_FLAG_NONE); \ |
INTERNAL_TRACE_EVENT_UID(profileScope).Initialize( \ |
INTERNAL_TRACE_EVENT_UID(catstatic), name); \ |
} |
@@ -375,15 +454,26 @@ |
if (INTERNAL_TRACE_EVENT_UID(catstatic)->enabled) { \ |
int INTERNAL_TRACE_EVENT_UID(begin_event_id) = \ |
base::debug::TraceLog::GetInstance()->AddTraceEvent( \ |
- base::debug::TRACE_EVENT_PHASE_BEGIN, \ |
+ TRACE_EVENT_PHASE_BEGIN, \ |
INTERNAL_TRACE_EVENT_UID(catstatic), \ |
- name, arg1_name, arg1_val, arg2_name, arg2_val, -1, 0, \ |
- base::debug::TraceLog::EVENT_FLAG_NONE); \ |
+ name, 0, arg1_name, arg1_val, arg2_name, arg2_val, -1, 0, \ |
+ TRACE_EVENT_FLAG_NONE); \ |
INTERNAL_TRACE_EVENT_UID(profileScope).Initialize( \ |
INTERNAL_TRACE_EVENT_UID(catstatic), name, \ |
INTERNAL_TRACE_EVENT_UID(begin_event_id), threshold); \ |
} |
+// 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, \ |
+ arg1_name, arg1_val, arg2_name, arg2_val, flags) \ |
+ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ |
+ if (INTERNAL_TRACE_EVENT_UID(catstatic)->enabled) { \ |
+ base::debug::TraceLog::GetInstance()->AddTraceEvent( \ |
+ phase, INTERNAL_TRACE_EVENT_UID(catstatic), \ |
+ name, id, arg1_name, arg1_val, arg2_name, arg2_val, -1, 0, flags); \ |
+ } |
+ |
template <typename Type> |
struct StaticMemorySingletonTraits; |
@@ -402,13 +492,19 @@ struct TraceCategory { |
const size_t kTraceMaxNumArgs = 2; |
// Phase indicates the nature of an event entry. E.g. part of a begin/end pair. |
-enum TraceEventPhase { |
- TRACE_EVENT_PHASE_BEGIN, |
- TRACE_EVENT_PHASE_END, |
- TRACE_EVENT_PHASE_INSTANT, |
- TRACE_EVENT_PHASE_METADATA, |
- TRACE_EVENT_PHASE_COUNTER |
-}; |
+typedef char TraceEventPhase; |
+#define TRACE_EVENT_PHASE_BEGIN (base::debug::TraceEventPhase('B')) |
+#define TRACE_EVENT_PHASE_END (base::debug::TraceEventPhase('E')) |
+#define TRACE_EVENT_PHASE_INSTANT (base::debug::TraceEventPhase('I')) |
+#define TRACE_EVENT_PHASE_START (base::debug::TraceEventPhase('S')) |
+#define TRACE_EVENT_PHASE_FINISH (base::debug::TraceEventPhase('F')) |
+#define TRACE_EVENT_PHASE_METADATA (base::debug::TraceEventPhase('M')) |
+#define TRACE_EVENT_PHASE_COUNTER (base::debug::TraceEventPhase('C')) |
+ |
+typedef uint8 TraceEventFlags; |
+#define TRACE_EVENT_FLAG_NONE (base::debug::TraceEventFlags(0)) |
+#define TRACE_EVENT_FLAG_COPY (base::debug::TraceEventFlags(1<<0)) |
+#define TRACE_EVENT_FLAG_HAS_ID (base::debug::TraceEventFlags(1<<1)) |
nduca
2011/12/01 02:55:26
<3
|
// Simple union of values. This is much lighter weight than base::Value, which |
// requires dynamic allocation and a vtable. To keep the trace runtime overhead |
@@ -535,6 +631,26 @@ class BASE_EXPORT TraceValue { |
Value value_; |
}; |
+// TraceID encapsulates an ID that can either be an integer or pointer. Pointers |
+// are mangled with the Process ID so that they are unlikely to collide when the |
+// same pointer is used on different processes. |
+class BASE_EXPORT TraceID { |
+ public: |
+ TraceID() : data_(NULL) {} |
+ TraceID(void* rhs); |
+ TraceID(unsigned long long rhs) : data_(static_cast<uint64>(rhs)) {} |
+ TraceID(unsigned long rhs) : data_(static_cast<uint64>(rhs)) {} |
+ TraceID(unsigned int rhs) : data_(static_cast<uint64>(rhs)) {} |
+ TraceID(long long rhs) : data_(static_cast<uint64>(rhs)) {} |
+ TraceID(long rhs) : data_(static_cast<uint64>(rhs)) {} |
+ TraceID(int rhs) : data_(static_cast<uint64>(rhs)) {} |
+ |
+ uint64 data() const { return data_; } |
+ |
+ private: |
+ uint64 data_; |
+}; |
+ |
// 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 |
@@ -542,19 +658,24 @@ class BASE_EXPORT TraceValue { |
class BASE_EXPORT TraceEvent { |
public: |
TraceEvent(); |
- TraceEvent(unsigned long process_id, |
- unsigned long thread_id, |
+ 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); |
+ TraceEventFlags flags); |
~TraceEvent(); |
- static const char* GetPhaseString(TraceEventPhase phase); |
- static TraceEventPhase GetPhase(const char* phase); |
+ static char GetPhaseChar(TraceEventPhase phase) { |
+ return static_cast<char>(phase); |
+ } |
+ |
+ static TraceEventPhase GetPhase(const char* phase) { |
+ return static_cast<TraceEventPhase>(*phase); |
+ } |
// Serialize event data to JSON |
static void AppendEventsAsJSON(const std::vector<TraceEvent>& events, |
@@ -574,15 +695,18 @@ class BASE_EXPORT TraceEvent { |
const char* name() const { return name_; } |
private: |
- unsigned long process_id_; |
- unsigned long thread_id_; |
+ // Note: these are ordered by size (largest first) for optimal packing. |
TimeTicks timestamp_; |
- TraceEventPhase phase_; |
+ // id_ can be used to store phase-specific data. |
+ TraceID id_; |
+ TraceValue arg_values_[kTraceMaxNumArgs]; |
+ const char* arg_names_[kTraceMaxNumArgs]; |
const TraceCategory* category_; |
const char* name_; |
- const char* arg_names_[kTraceMaxNumArgs]; |
- TraceValue arg_values_[kTraceMaxNumArgs]; |
scoped_refptr<base::RefCountedString> parameter_copy_storage_; |
+ int thread_id_; |
+ TraceEventPhase phase_; |
+ TraceEventFlags flags_; |
}; |
@@ -632,12 +756,6 @@ class BASE_EXPORT TraceResultBuffer { |
class BASE_EXPORT TraceLog { |
public: |
- // Flags for passing to AddTraceEvent. |
- enum EventFlags { |
- EVENT_FLAG_NONE = 0, |
- EVENT_FLAG_COPY = 1<<0 |
- }; |
- |
static TraceLog* GetInstance(); |
// Get set of known categories. This can change as new code paths are reached. |
@@ -710,11 +828,12 @@ class BASE_EXPORT TraceLog { |
int 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); |
static void AddTraceEventEtw(TraceEventPhase phase, |
const char* name, |
const void* id, |
@@ -730,7 +849,13 @@ class BASE_EXPORT TraceLog { |
const char* name, |
const char* arg1_name, int32 arg1_val, |
const char* arg2_name, int32 arg2_val, |
- EventFlags flags); |
+ TraceEventFlags flags); |
+ |
+ // Mangle |id| with a hash based on the process ID so that if |id| occurs on |
+ // more than one process, it will not collide. |
+ uint64 GetIntraProcessID(uint64 id) const { return id ^ process_id_hash_; } |
nduca
2011/12/01 02:55:26
Why this versus just tracking id and a bool flag s
jbates
2011/12/01 23:07:50
Sounds good, but sadly I think I would have to dou
|
+ |
+ int process_id() const { return process_id_; } |
// Exposed for unittesting: |
@@ -747,6 +872,8 @@ class BASE_EXPORT TraceLog { |
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. |
@@ -767,7 +894,12 @@ class BASE_EXPORT TraceLog { |
std::vector<std::string> included_categories_; |
std::vector<std::string> excluded_categories_; |
- base::hash_map<PlatformThreadId, std::string> thread_names_; |
+ base::hash_map<int, std::string> thread_names_; |
+ |
+ // XORed with TraceID to make it unlikely to collide with other processes. |
+ uint64 process_id_hash_; |
+ |
+ int process_id_; |
DISALLOW_COPY_AND_ASSIGN(TraceLog); |
}; |