OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/debug/trace_event_impl.h" | 5 #include "base/debug/trace_event_impl.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/stringprintf.h" | 12 #include "base/stringprintf.h" |
13 | 13 |
14 namespace { | 14 namespace { |
15 | 15 |
16 int g_atrace_fd = -1; | 16 int g_atrace_fd = -1; |
17 const char* kATraceMarkerFile = "/sys/kernel/debug/tracing/trace_marker"; | 17 const char* kATraceMarkerFile = "/sys/kernel/debug/tracing/trace_marker"; |
18 | 18 |
19 void WriteEvent(char phase, | 19 void WriteEvent(char phase, |
20 const char* category, | 20 const char* category_group, |
21 const char* name, | 21 const char* name, |
22 unsigned long long id, | 22 unsigned long long id, |
23 int num_args, | 23 int num_args, |
24 const char** arg_names, | 24 const char** arg_names, |
25 const unsigned char* arg_types, | 25 const unsigned char* arg_types, |
26 const unsigned long long* arg_values, | 26 const unsigned long long* arg_values, |
27 unsigned char flags) { | 27 unsigned char flags) { |
28 std::string out = base::StringPrintf("%c|%d|%s", phase, getpid(), name); | 28 std::string out = base::StringPrintf("%c|%d|%s", phase, getpid(), name); |
29 if (flags & TRACE_EVENT_FLAG_HAS_ID) | 29 if (flags & TRACE_EVENT_FLAG_HAS_ID) |
30 base::StringAppendF(&out, "-%" PRIx64, static_cast<uint64>(id)); | 30 base::StringAppendF(&out, "-%" PRIx64, static_cast<uint64>(id)); |
(...skipping 10 matching lines...) Expand all Loading... |
41 base::debug::TraceEvent::AppendValueAsJSON(arg_types[i], value, &out); | 41 base::debug::TraceEvent::AppendValueAsJSON(arg_types[i], value, &out); |
42 // Remove the quotes which may confuse the atrace script. | 42 // Remove the quotes which may confuse the atrace script. |
43 ReplaceSubstringsAfterOffset(&out, value_start, "\\\"", "'"); | 43 ReplaceSubstringsAfterOffset(&out, value_start, "\\\"", "'"); |
44 ReplaceSubstringsAfterOffset(&out, value_start, "\"", ""); | 44 ReplaceSubstringsAfterOffset(&out, value_start, "\"", ""); |
45 // Replace chars used for separators with similar chars in the value. | 45 // Replace chars used for separators with similar chars in the value. |
46 std::replace(out.begin() + value_start, out.end(), ';', ','); | 46 std::replace(out.begin() + value_start, out.end(), ';', ','); |
47 std::replace(out.begin() + value_start, out.end(), '|', '!'); | 47 std::replace(out.begin() + value_start, out.end(), '|', '!'); |
48 } | 48 } |
49 | 49 |
50 out += '|'; | 50 out += '|'; |
51 out += category; | 51 out += category_group; |
52 write(g_atrace_fd, out.c_str(), out.size()); | 52 write(g_atrace_fd, out.c_str(), out.size()); |
53 } | 53 } |
54 | 54 |
55 } // namespace | 55 } // namespace |
56 | 56 |
57 namespace base { | 57 namespace base { |
58 namespace debug { | 58 namespace debug { |
59 | 59 |
60 void TraceLog::StartATrace() { | 60 void TraceLog::StartATrace() { |
61 AutoLock lock(lock_); | 61 AutoLock lock(lock_); |
62 if (g_atrace_fd == -1) { | 62 if (g_atrace_fd == -1) { |
63 g_atrace_fd = open(kATraceMarkerFile, O_WRONLY); | 63 g_atrace_fd = open(kATraceMarkerFile, O_WRONLY); |
64 if (g_atrace_fd == -1) | 64 if (g_atrace_fd == -1) |
65 LOG(WARNING) << "Couldn't open " << kATraceMarkerFile; | 65 LOG(WARNING) << "Couldn't open " << kATraceMarkerFile; |
66 } | 66 } |
67 } | 67 } |
68 | 68 |
69 void TraceLog::StopATrace() { | 69 void TraceLog::StopATrace() { |
70 AutoLock lock(lock_); | 70 AutoLock lock(lock_); |
71 if (g_atrace_fd != -1) { | 71 if (g_atrace_fd != -1) { |
72 close(g_atrace_fd); | 72 close(g_atrace_fd); |
73 g_atrace_fd = -1; | 73 g_atrace_fd = -1; |
74 } | 74 } |
75 } | 75 } |
76 | 76 |
77 void TraceLog::SendToATrace(char phase, | 77 void TraceLog::SendToATrace(char phase, |
78 const char* category, | 78 const char* category_group, |
79 const char* name, | 79 const char* name, |
80 unsigned long long id, | 80 unsigned long long id, |
81 int num_args, | 81 int num_args, |
82 const char** arg_names, | 82 const char** arg_names, |
83 const unsigned char* arg_types, | 83 const unsigned char* arg_types, |
84 const unsigned long long* arg_values, | 84 const unsigned long long* arg_values, |
85 unsigned char flags) { | 85 unsigned char flags) { |
86 if (g_atrace_fd == -1) | 86 if (g_atrace_fd == -1) |
87 return; | 87 return; |
88 | 88 |
89 switch (phase) { | 89 switch (phase) { |
90 case TRACE_EVENT_PHASE_BEGIN: | 90 case TRACE_EVENT_PHASE_BEGIN: |
91 WriteEvent('B', category, name, id, | 91 WriteEvent('B', category_group, name, id, |
92 num_args, arg_names, arg_types, arg_values, flags); | 92 num_args, arg_names, arg_types, arg_values, flags); |
93 break; | 93 break; |
94 | 94 |
95 case TRACE_EVENT_PHASE_END: | 95 case TRACE_EVENT_PHASE_END: |
96 // Though a single 'E' is enough, here append pid, name and category etc. | 96 // Though a single 'E' is enough, here append pid, name and |
97 // so that unpaired events can be found easily. | 97 // category_group etc. So that unpaired events can be found easily. |
98 WriteEvent('E', category, name, id, | 98 WriteEvent('E', category_group, name, id, |
99 num_args, arg_names, arg_types, arg_values, flags); | 99 num_args, arg_names, arg_types, arg_values, flags); |
100 break; | 100 break; |
101 | 101 |
102 case TRACE_EVENT_PHASE_INSTANT: | 102 case TRACE_EVENT_PHASE_INSTANT: |
103 // Simulate an instance event with a pair of begin/end events. | 103 // Simulate an instance event with a pair of begin/end events. |
104 WriteEvent('B', category, name, id, | 104 WriteEvent('B', category_group, name, id, |
105 num_args, arg_names, arg_types, arg_values, flags); | 105 num_args, arg_names, arg_types, arg_values, flags); |
106 write(g_atrace_fd, "E", 1); | 106 write(g_atrace_fd, "E", 1); |
107 break; | 107 break; |
108 | 108 |
109 case TRACE_EVENT_PHASE_COUNTER: | 109 case TRACE_EVENT_PHASE_COUNTER: |
110 for (int i = 0; i < num_args; ++i) { | 110 for (int i = 0; i < num_args; ++i) { |
111 DCHECK(arg_types[i] == TRACE_VALUE_TYPE_INT); | 111 DCHECK(arg_types[i] == TRACE_VALUE_TYPE_INT); |
112 std::string out = base::StringPrintf("C|%d|%s-%s", | 112 std::string out = base::StringPrintf("C|%d|%s-%s", |
113 getpid(), name, arg_names[i]); | 113 getpid(), name, arg_names[i]); |
114 if (flags & TRACE_EVENT_FLAG_HAS_ID) | 114 if (flags & TRACE_EVENT_FLAG_HAS_ID) |
115 StringAppendF(&out, "-%" PRIx64, static_cast<uint64>(id)); | 115 StringAppendF(&out, "-%" PRIx64, static_cast<uint64>(id)); |
116 StringAppendF(&out, "|%d|%s", | 116 StringAppendF(&out, "|%d|%s", |
117 static_cast<int>(arg_values[i]), category); | 117 static_cast<int>(arg_values[i]), category_group); |
118 write(g_atrace_fd, out.c_str(), out.size()); | 118 write(g_atrace_fd, out.c_str(), out.size()); |
119 } | 119 } |
120 break; | 120 break; |
121 | 121 |
122 default: | 122 default: |
123 // Do nothing. | 123 // Do nothing. |
124 break; | 124 break; |
125 } | 125 } |
126 } | 126 } |
127 | 127 |
128 // Must be called with lock_ locked. | 128 // Must be called with lock_ locked. |
129 void TraceLog::ApplyATraceEnabledFlag(unsigned char* category_enabled) { | 129 void TraceLog::ApplyATraceEnabledFlag(unsigned char* category_group_enabled) { |
130 if (g_atrace_fd != -1) | 130 if (g_atrace_fd != -1) |
131 *category_enabled |= ATRACE_ENABLED; | 131 *category_group_enabled |= ATRACE_ENABLED; |
132 else | 132 else |
133 *category_enabled &= ~ATRACE_ENABLED; | 133 *category_group_enabled &= ~ATRACE_ENABLED; |
134 } | 134 } |
135 | 135 |
136 } // namespace debug | 136 } // namespace debug |
137 } // namespace base | 137 } // namespace base |
OLD | NEW |