Commit ec9bfc85 authored by kelvinjin's avatar kelvinjin Committed by Commit bot

[Tracing] Minor bug fixes related to trace serialization

Escape sequences may now be written to a trace file (previously,
any string with a valid escapable character would fail a check).

Also, string properties are now surrounded with quotes.

BUG=v8:4561

Review-Url: https://codereview.chromium.org/2309943005
Cr-Commit-Position: refs/heads/master@{#39319}
parent 0027218e
...@@ -13,17 +13,45 @@ namespace v8 { ...@@ -13,17 +13,45 @@ namespace v8 {
namespace platform { namespace platform {
namespace tracing { namespace tracing {
// Currently we do not support JSON-escaping strings in trace arguments. // Writes the given string to a stream, taking care to escape characters
// Thus we perform an IsJSONString() check before writing any string argument. // when necessary.
// In particular, this means strings cannot have control characters or \. V8_INLINE static void WriteJSONStringToStream(const char* str,
V8_INLINE static bool IsJSONString(const char* str) { std::ostream& stream) {
size_t len = strlen(str); size_t len = strlen(str);
stream << "\"";
for (size_t i = 0; i < len; ++i) { for (size_t i = 0; i < len; ++i) {
if (iscntrl(str[i]) || str[i] == '\\') { // All of the permitted escape sequences in JSON strings, as per
return false; // https://mathiasbynens.be/notes/javascript-escapes
switch (str[i]) {
case '\b':
stream << "\\b";
break;
case '\f':
stream << "\\f";
break;
case '\n':
stream << "\\n";
break;
case '\r':
stream << "\\r";
break;
case '\t':
stream << "\\t";
break;
case '\"':
stream << "\\\"";
break;
case '\\':
stream << "\\\\";
break;
// Note that because we use double quotes for JSON strings,
// we don't need to escape single quotes.
default:
stream << str[i];
break;
} }
} }
return true; stream << "\"";
} }
void JSONTraceWriter::AppendArgValue(uint8_t type, void JSONTraceWriter::AppendArgValue(uint8_t type,
...@@ -72,10 +100,11 @@ void JSONTraceWriter::AppendArgValue(uint8_t type, ...@@ -72,10 +100,11 @@ void JSONTraceWriter::AppendArgValue(uint8_t type,
break; break;
case TRACE_VALUE_TYPE_STRING: case TRACE_VALUE_TYPE_STRING:
case TRACE_VALUE_TYPE_COPY_STRING: case TRACE_VALUE_TYPE_COPY_STRING:
// Strings are currently not JSON-escaped, so we need to perform a check if (value.as_string == nullptr) {
// to see if they are valid JSON strings. stream_ << "\"NULL\"";
CHECK(value.as_string != nullptr && IsJSONString(value.as_string)); } else {
stream_ << (value.as_string ? value.as_string : "NULL"); WriteJSONStringToStream(value.as_string, stream_);
}
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
......
...@@ -217,7 +217,7 @@ TEST(TestTracingControllerMultipleArgsAndCopy) { ...@@ -217,7 +217,7 @@ TEST(TestTracingControllerMultipleArgsAndCopy) {
double jj4 = std::numeric_limits<double>::infinity(); double jj4 = std::numeric_limits<double>::infinity();
double jj5 = -std::numeric_limits<double>::infinity(); double jj5 = -std::numeric_limits<double>::infinity();
void* kk = &aa; void* kk = &aa;
const char* ll = "\"100\""; const char* ll = "100";
std::string mm = "INIT"; std::string mm = "INIT";
std::string mmm = "\"INIT\""; std::string mmm = "\"INIT\"";
...@@ -254,15 +254,13 @@ TEST(TestTracingControllerMultipleArgsAndCopy) { ...@@ -254,15 +254,13 @@ TEST(TestTracingControllerMultipleArgsAndCopy) {
TRACE_EVENT1("v8", "v8.Test.mm", "mm", TRACE_STR_COPY(mmm.c_str())); TRACE_EVENT1("v8", "v8.Test.mm", "mm", TRACE_STR_COPY(mmm.c_str()));
TRACE_EVENT2("v8", "v8.Test2.1", "aa", aa, "ll", ll); TRACE_EVENT2("v8", "v8.Test2.1", "aa", aa, "ll", ll);
TRACE_EVENT2("v8", "v8.Test2.2", "mm1", TRACE_STR_COPY(mmm.c_str()), "mm2", TRACE_EVENT2("v8", "v8.Test2.2", "mm1", TRACE_STR_COPY(mm.c_str()), "mm2",
TRACE_STR_COPY(mmm.c_str())); TRACE_STR_COPY(mmm.c_str()));
// Check copies are correct. // Check copies are correct.
TRACE_EVENT_COPY_INSTANT0("v8", mm.c_str(), TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_COPY_INSTANT0("v8", mm.c_str(), TRACE_EVENT_SCOPE_THREAD);
TRACE_EVENT_COPY_INSTANT1("v8", mm.c_str(), TRACE_EVENT_SCOPE_THREAD, TRACE_EVENT_COPY_INSTANT2("v8", mm.c_str(), TRACE_EVENT_SCOPE_THREAD, "mm1",
mm.c_str(), mmm.c_str()); mm.c_str(), "mm2", mmm.c_str());
TRACE_EVENT_COPY_INSTANT2("v8", mm.c_str(), TRACE_EVENT_SCOPE_THREAD,
mm.c_str(), mmm.c_str(), mm.c_str(), mmm.c_str());
mm = "CHANGED"; mm = "CHANGED";
mmm = "CHANGED"; mmm = "CHANGED";
...@@ -276,7 +274,7 @@ TEST(TestTracingControllerMultipleArgsAndCopy) { ...@@ -276,7 +274,7 @@ TEST(TestTracingControllerMultipleArgsAndCopy) {
GetJSONStrings(all_names, trace_str, "\"name\"", "\"", "\""); GetJSONStrings(all_names, trace_str, "\"name\"", "\"", "\"");
GetJSONStrings(all_cats, trace_str, "\"cat\"", "\"", "\""); GetJSONStrings(all_cats, trace_str, "\"cat\"", "\"", "\"");
CHECK_EQ(all_args.size(), 23); CHECK_EQ(all_args.size(), 22);
CHECK_EQ(all_args[0], "\"aa\":11"); CHECK_EQ(all_args[0], "\"aa\":11");
CHECK_EQ(all_args[1], "\"bb\":22"); CHECK_EQ(all_args[1], "\"bb\":22");
CHECK_EQ(all_args[2], "\"cc\":33"); CHECK_EQ(all_args[2], "\"cc\":33");
...@@ -296,17 +294,15 @@ TEST(TestTracingControllerMultipleArgsAndCopy) { ...@@ -296,17 +294,15 @@ TEST(TestTracingControllerMultipleArgsAndCopy) {
pointer_stream << "\"kk\":\"" << &aa << "\""; pointer_stream << "\"kk\":\"" << &aa << "\"";
CHECK_EQ(all_args[15], pointer_stream.str()); CHECK_EQ(all_args[15], pointer_stream.str());
CHECK_EQ(all_args[16], "\"ll\":\"100\""); CHECK_EQ(all_args[16], "\"ll\":\"100\"");
CHECK_EQ(all_args[17], "\"mm\":\"INIT\""); CHECK_EQ(all_args[17], "\"mm\":\"\\\"INIT\\\"\"");
CHECK_EQ(all_names[18], "v8.Test2.1"); CHECK_EQ(all_names[18], "v8.Test2.1");
CHECK_EQ(all_args[18], "\"aa\":11,\"ll\":\"100\""); CHECK_EQ(all_args[18], "\"aa\":11,\"ll\":\"100\"");
CHECK_EQ(all_args[19], "\"mm1\":\"INIT\",\"mm2\":\"INIT\""); CHECK_EQ(all_args[19], "\"mm1\":\"INIT\",\"mm2\":\"\\\"INIT\\\"\"");
CHECK_EQ(all_names[20], "INIT"); CHECK_EQ(all_names[20], "INIT");
CHECK_EQ(all_names[21], "INIT"); CHECK_EQ(all_names[21], "INIT");
CHECK_EQ(all_args[21], "\"INIT\":\"INIT\""); CHECK_EQ(all_args[21], "\"mm1\":\"INIT\",\"mm2\":\"\\\"INIT\\\"\"");
CHECK_EQ(all_names[22], "INIT");
CHECK_EQ(all_args[22], "\"INIT\":\"INIT\",\"INIT\":\"INIT\"");
i::V8::SetPlatformForTesting(old_platform); i::V8::SetPlatformForTesting(old_platform);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment