[trace-engine] Fix bug writing arguments within inline names.
Change-Id: I5cbaa3cec12c0423546e3e6db76d8bea9257cfea
diff --git a/system/ulib/trace-engine/context.cpp b/system/ulib/trace-engine/context.cpp
index 5fb2401..c92233a 100644
--- a/system/ulib/trace-engine/context.cpp
+++ b/system/ulib/trace-engine/context.cpp
@@ -7,12 +7,12 @@
#include <magenta/compiler.h>
#include <magenta/syscalls.h>
-#include <mx/process.h>
-#include <mx/thread.h>
#include <fbl/algorithm.h>
#include <fbl/atomic.h>
#include <fbl/intrusive_hash_table.h>
#include <fbl/unique_ptr.h>
+#include <mx/process.h>
+#include <mx/thread.h>
#include <trace-engine/fields.h>
namespace trace {
@@ -169,7 +169,7 @@
size_t SizeOfEncodedStringRef(const trace_string_ref_t* string_ref) {
return trace_is_inline_string_ref(string_ref)
- ? Pad(string_ref->encoded_value & TRACE_ENCODED_STRING_REF_LENGTH_MASK)
+ ? Pad(trace_inline_string_ref_length(string_ref))
: 0u;
}
@@ -277,41 +277,41 @@
Payload& WriteArg(const trace_arg_t* arg) {
switch (arg->value.type) {
case TRACE_ARG_NULL:
- WriteArgumentHeader(ArgumentType::kNull, &arg->name_ref, 0u, 0u);
+ WriteArgumentHeaderAndName(ArgumentType::kNull, &arg->name_ref, 0u, 0u);
break;
case TRACE_ARG_INT32:
- WriteArgumentHeader(ArgumentType::kInt32, &arg->name_ref, 0u,
- Int32ArgumentFields::Value::Make(arg->value.int32_value));
+ WriteArgumentHeaderAndName(ArgumentType::kInt32, &arg->name_ref, 0u,
+ Int32ArgumentFields::Value::Make(arg->value.int32_value));
break;
case TRACE_ARG_UINT32:
- WriteArgumentHeader(ArgumentType::kUint32, &arg->name_ref, 0u,
- Uint32ArgumentFields::Value::Make(arg->value.uint32_value));
+ WriteArgumentHeaderAndName(ArgumentType::kUint32, &arg->name_ref, 0u,
+ Uint32ArgumentFields::Value::Make(arg->value.uint32_value));
break;
case TRACE_ARG_INT64:
- WriteArgumentHeader(ArgumentType::kInt64, &arg->name_ref, WordsToBytes(1), 0u);
+ WriteArgumentHeaderAndName(ArgumentType::kInt64, &arg->name_ref, WordsToBytes(1), 0u);
WriteInt64(arg->value.int64_value);
break;
case TRACE_ARG_UINT64:
- WriteArgumentHeader(ArgumentType::kUint64, &arg->name_ref, WordsToBytes(1), 0u);
+ WriteArgumentHeaderAndName(ArgumentType::kUint64, &arg->name_ref, WordsToBytes(1), 0u);
WriteUint64(arg->value.uint64_value);
break;
case TRACE_ARG_DOUBLE:
- WriteArgumentHeader(ArgumentType::kDouble, &arg->name_ref, WordsToBytes(1), 0u);
+ WriteArgumentHeaderAndName(ArgumentType::kDouble, &arg->name_ref, WordsToBytes(1), 0u);
WriteDouble(arg->value.double_value);
break;
case TRACE_ARG_STRING:
- WriteArgumentHeader(ArgumentType::kString, &arg->name_ref,
- SizeOfEncodedStringRef(&arg->value.string_value_ref),
- StringArgumentFields::Index::Make(
- arg->value.string_value_ref.encoded_value));
+ WriteArgumentHeaderAndName(ArgumentType::kString, &arg->name_ref,
+ SizeOfEncodedStringRef(&arg->value.string_value_ref),
+ StringArgumentFields::Index::Make(
+ arg->value.string_value_ref.encoded_value));
WriteStringRef(&arg->value.string_value_ref);
break;
case TRACE_ARG_POINTER:
- WriteArgumentHeader(ArgumentType::kPointer, &arg->name_ref, WordsToBytes(1), 0u);
+ WriteArgumentHeaderAndName(ArgumentType::kPointer, &arg->name_ref, WordsToBytes(1), 0u);
WriteUint64(arg->value.pointer_value);
break;
case TRACE_ARG_KOID:
- WriteArgumentHeader(ArgumentType::kKoid, &arg->name_ref, WordsToBytes(1), 0u);
+ WriteArgumentHeaderAndName(ArgumentType::kKoid, &arg->name_ref, WordsToBytes(1), 0u);
WriteUint64(arg->value.koid_value);
break;
default:
@@ -329,14 +329,15 @@
}
private:
- void WriteArgumentHeader(ArgumentType type,
- const trace_string_ref_t* name_ref,
- size_t content_size,
- uint64_t header_bits) {
+ void WriteArgumentHeaderAndName(ArgumentType type,
+ const trace_string_ref_t* name_ref,
+ size_t content_size,
+ uint64_t header_bits) {
const size_t argument_size = sizeof(ArgumentHeader) +
SizeOfEncodedStringRef(name_ref) +
content_size;
WriteUint64(MakeArgumentHeader(type, argument_size, name_ref) | header_bits);
+ WriteStringRef(name_ref);
}
uint64_t* ptr_;
diff --git a/system/ulib/trace-engine/include/trace-engine/types.h b/system/ulib/trace-engine/include/trace-engine/types.h
index 39540cb..94c8dbf 100644
--- a/system/ulib/trace-engine/include/trace-engine/types.h
+++ b/system/ulib/trace-engine/include/trace-engine/types.h
@@ -90,7 +90,7 @@
// Returns the length of an inline string.
// Only valid for inline strings.
inline size_t trace_inline_string_ref_length(const trace_string_ref_t* string_ref) {
- return string_ref->encoded_value & ~TRACE_ENCODED_STRING_REF_INLINE_FLAG;
+ return string_ref->encoded_value & TRACE_ENCODED_STRING_REF_LENGTH_MASK;
}
// Makes an empty string ref.
diff --git a/system/utest/trace/engine_tests.cpp b/system/utest/trace/engine_tests.cpp
index 35cecb0..8c086d9 100644
--- a/system/utest/trace/engine_tests.cpp
+++ b/system/utest/trace/engine_tests.cpp
@@ -6,11 +6,11 @@
#include <threads.h>
-#include <mx/event.h>
#include <fbl/function.h>
#include <fbl/string.h>
#include <fbl/string_printf.h>
#include <fbl/vector.h>
+#include <mx/event.h>
#include <trace-engine/instrumentation.h>
namespace {
@@ -359,6 +359,34 @@
END_TRACE_TEST;
}
+bool test_event_with_inline_everything() {
+ BEGIN_TRACE_TEST;
+
+ fixture_start_tracing();
+
+ trace_string_ref_t cat = trace_make_inline_c_string_ref("cat");
+ trace_string_ref_t name = trace_make_inline_c_string_ref("name");
+ trace_thread_ref_t thread = trace_make_inline_thread_ref(123, 456);
+ trace_arg_t args[] = {
+ trace_make_arg(trace_make_inline_c_string_ref("argname"),
+ trace_make_string_arg_value(trace_make_inline_c_string_ref("argvalue")))};
+
+ {
+ auto context = trace::TraceContext::Acquire();
+
+ trace_context_write_instant_event_record(context.get(), mx_ticks_get(),
+ &thread, &cat, &name,
+ TRACE_SCOPE_GLOBAL,
+ args, fbl::count_of(args));
+ }
+
+ ASSERT_RECORDS(R"X(Event(ts: <>, pt: <>, category: "cat", name: "name", Instant(scope: global), {argname: string("argvalue")})
+)X",
+ "");
+
+ END_TRACE_TEST;
+}
+
// NOTE: The functions for writing trace records are exercised by other trace tests.
} // namespace
@@ -377,4 +405,5 @@
RUN_TEST(test_register_string_literal_multiple_threads)
RUN_TEST(test_register_string_literal_table_overflow)
RUN_TEST(test_maximum_record_length)
+RUN_TEST(test_event_with_inline_everything)
END_TEST_CASE(engine_tests)