Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Unified Diff: webrtc/base/event_tracer.cc

Issue 2215153003: Add argument support for stand-alone WebRTC tracing. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fix warning about print_length being uninitialized. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/base/event_tracer.cc
diff --git a/webrtc/base/event_tracer.cc b/webrtc/base/event_tracer.cc
index 85d5c0b17b60a5531a2d1cb56803f97d0627e731..4393bff2985884a746ad3a330d962294afc6e60f 100644
--- a/webrtc/base/event_tracer.cc
+++ b/webrtc/base/event_tracer.cc
@@ -11,6 +11,7 @@
#include <inttypes.h>
+#include <string>
#include <vector>
#include "webrtc/base/checks.h"
@@ -18,9 +19,14 @@
#include "webrtc/base/event.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/platform_thread.h"
+#include "webrtc/base/stringutils.h"
#include "webrtc/base/timeutils.h"
#include "webrtc/base/trace_event.h"
+// This is a guesstimate that should be enough in most cases.
+static const size_t kEventLoggerArgsStrBufferInitialSize = 256;
+static const size_t kTraceArgBufferLength = 32;
+
namespace webrtc {
namespace {
@@ -90,12 +96,32 @@ class EventLogger final {
void AddTraceEvent(const char* name,
const unsigned char* category_enabled,
char phase,
+ int num_args,
+ const char** arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
uint64_t timestamp,
int pid,
rtc::PlatformThreadId thread_id) {
+ std::vector<TraceArg> args(num_args);
+ for (int i = 0; i < num_args; ++i) {
+ TraceArg& arg = args[i];
+ arg.name = arg_names[i];
+ arg.type = arg_types[i];
+ arg.value.as_uint = arg_values[i];
+
+ // Value is a pointer to a temporary string, so we have to make a copy.
+ if (arg.type == TRACE_VALUE_TYPE_COPY_STRING) {
+ // Space for the string and for the terminating null character.
+ size_t str_length = strlen(arg.value.as_string) + 1;
+ char* str_copy = new char[str_length];
+ memcpy(str_copy, arg.value.as_string, str_length);
+ arg.value.as_string = str_copy;
+ }
+ }
rtc::CritScope lock(&crit_);
trace_events_.push_back(
- {name, category_enabled, phase, timestamp, 1, thread_id});
+ {name, category_enabled, phase, args, timestamp, 1, thread_id});
}
// The TraceEvent format is documented here:
@@ -112,7 +138,30 @@ class EventLogger final {
rtc::CritScope lock(&crit_);
trace_events_.swap(events);
}
- for (const TraceEvent& e : events) {
+ std::string args_str;
+ args_str.reserve(kEventLoggerArgsStrBufferInitialSize);
+ for (TraceEvent& e : events) {
+ args_str.clear();
+ if (!e.args.empty()) {
+ args_str += ", \"args\": {";
+ bool is_first_argument = true;
+ for (TraceArg& arg : e.args) {
+ if (!is_first_argument)
+ args_str += ",";
+ is_first_argument = false;
+ args_str += " \"";
+ args_str += arg.name;
+ args_str += "\": ";
+ args_str += TraceArgValueAsString(arg);
+
+ // Delete our copy of the string.
+ if (arg.type == TRACE_VALUE_TYPE_COPY_STRING) {
+ delete[] arg.value.as_string;
+ arg.value.as_string = nullptr;
+ }
+ }
+ args_str += " }";
+ }
fprintf(output_file_,
"%s{ \"name\": \"%s\""
", \"cat\": \"%s\""
@@ -124,9 +173,10 @@ class EventLogger final {
#else
", \"tid\": %d"
#endif // defined(WEBRTC_WIN)
+ "%s"
"}\n",
has_logged_event ? "," : " ", e.name, e.category_enabled,
- e.phase, e.timestamp, e.pid, e.tid);
+ e.phase, e.timestamp, e.pid, e.tid, args_str.c_str());
has_logged_event = true;
}
if (shutting_down)
@@ -177,15 +227,96 @@ class EventLogger final {
}
private:
+ struct TraceArg {
+ const char* name;
+ unsigned char type;
+ // Copied from webrtc/base/trace_event.h TraceValueUnion.
+ union TraceArgValue {
+ bool as_bool;
+ unsigned long long as_uint;
+ long long as_int;
+ double as_double;
+ const void* as_pointer;
+ const char* as_string;
+ } value;
+
+ // Assert that the size of the union is equal to the size of the as_uint
+ // field since we are assigning to arbitrary types using it.
+ static_assert(sizeof(TraceArgValue) == sizeof(unsigned long long),
+ "Size of TraceArg value union is not equal to the size of "
+ "the uint field of that union.");
+ };
+
struct TraceEvent {
const char* name;
const unsigned char* category_enabled;
char phase;
+ std::vector<TraceArg> args;
uint64_t timestamp;
int pid;
rtc::PlatformThreadId tid;
};
+ static std::string TraceArgValueAsString(TraceArg arg) {
+ std::string output;
+
+ if (arg.type == TRACE_VALUE_TYPE_STRING ||
+ arg.type == TRACE_VALUE_TYPE_COPY_STRING) {
+ // Space for every character to be an espaced character + two for
+ // quatation marks.
+ output.reserve(strlen(arg.value.as_string) * 2 + 2);
+ output += '\"';
+ const char* c = arg.value.as_string;
+ do {
+ if (*c == '"' || *c == '\\') {
+ output += '\\';
+ output += *c;
+ } else {
+ output += *c;
+ }
+ } while (*++c);
+ output += '\"';
+ } else {
+ output.resize(kTraceArgBufferLength);
+ size_t print_length = 0;
+ switch (arg.type) {
+ case TRACE_VALUE_TYPE_BOOL:
+ if (arg.value.as_bool) {
+ strcpy(&output[0], "true");
+ print_length = 4;
+ } else {
+ strcpy(&output[0], "false");
+ print_length = 5;
+ }
+ break;
+ case TRACE_VALUE_TYPE_UINT:
+ print_length = sprintfn(&output[0], kTraceArgBufferLength, "%llu",
+ arg.value.as_uint);
+ break;
+ case TRACE_VALUE_TYPE_INT:
+ print_length = sprintfn(&output[0], kTraceArgBufferLength, "%lld",
+ arg.value.as_int);
+ break;
+ case TRACE_VALUE_TYPE_DOUBLE:
+ print_length = sprintfn(&output[0], kTraceArgBufferLength, "%f",
+ arg.value.as_double);
+ break;
+ case TRACE_VALUE_TYPE_POINTER:
+ print_length = sprintfn(&output[0], kTraceArgBufferLength, "\"%p\"",
+ arg.value.as_pointer);
+ break;
+ }
+ size_t output_length = print_length < kTraceArgBufferLength
+ ? print_length
+ : kTraceArgBufferLength - 1;
+ // This will hopefully be very close to nop. On most implementations, it
+ // just writes null byte and sets the length field of the string.
+ output.resize(output_length);
+ }
+
+ return output;
+ }
+
rtc::CriticalSection crit_;
std::vector<TraceEvent> trace_events_ GUARDED_BY(crit_);
rtc::PlatformThread logging_thread_;
@@ -229,7 +360,8 @@ void InternalAddTraceEvent(char phase,
if (rtc::AtomicOps::AcquireLoad(&g_event_logging_active) == 0)
return;
- g_event_logger->AddTraceEvent(name, category_enabled, phase,
+ g_event_logger->AddTraceEvent(name, category_enabled, phase, num_args,
+ arg_names, arg_types, arg_values,
rtc::TimeMicros(), 1, rtc::CurrentThreadId());
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698