diff options
Diffstat (limited to 'src/trace_processor/sqlite/sqlite_raw_table.cc')
-rw-r--r-- | src/trace_processor/sqlite/sqlite_raw_table.cc | 227 |
1 files changed, 126 insertions, 101 deletions
diff --git a/src/trace_processor/sqlite/sqlite_raw_table.cc b/src/trace_processor/sqlite/sqlite_raw_table.cc index b02abf4e0..a42d83baa 100644 --- a/src/trace_processor/sqlite/sqlite_raw_table.cc +++ b/src/trace_processor/sqlite/sqlite_raw_table.cc @@ -16,7 +16,7 @@ #include "src/trace_processor/sqlite/sqlite_raw_table.h" -#include <inttypes.h> +#include <cinttypes> #include "perfetto/base/compiler.h" #include "perfetto/ext/base/string_utils.h" @@ -29,6 +29,7 @@ #include "src/trace_processor/types/variadic.h" #include "protos/perfetto/trace/ftrace/binder.pbzero.h" +#include "protos/perfetto/trace/ftrace/cgroup.pbzero.h" #include "protos/perfetto/trace/ftrace/clk.pbzero.h" #include "protos/perfetto/trace/ftrace/dpu.pbzero.h" #include "protos/perfetto/trace/ftrace/filemap.pbzero.h" @@ -58,7 +59,7 @@ class ArgsSerializer { ArgsSerializer(TraceProcessorContext*, ArgSetId arg_set_id, NullTermStringView event_name, - std::vector<uint32_t>* field_id_to_arg_index, + std::vector<base::Optional<uint32_t>>* field_id_to_arg_index, base::StringWriter*); void SerializeArgs(); @@ -67,43 +68,35 @@ class ArgsSerializer { using ValueWriter = std::function<void(const Variadic&)>; using SerializerValueWriter = void (ArgsSerializer::*)(const Variadic&); - void WriteArgForField(uint32_t field_id) { - WriteArgForField(field_id, - [this](const Variadic& v) { return WriteValue(v); }); - } - - void WriteArgForField(uint32_t field_id, SerializerValueWriter writer) { - WriteArgForField(field_id, [this, writer](const Variadic& variadic) { - (this->*writer)(variadic); - }); - } - + // Arg writing functions. void WriteArgForField(uint32_t field_id, ValueWriter writer) { - WriteArgAtRow(FieldIdToRow(field_id), writer); + base::Optional<uint32_t> row = FieldIdToRow(field_id); + if (!row) + return; + WriteArgAtRow(*row, writer); } - - void WriteValueForField(uint32_t field_id) { - WriteValueForField(field_id, - [this](const Variadic& v) { return WriteValue(v); }); + void WriteArgForField(uint32_t field_id, + base::StringView key, + ValueWriter writer) { + base::Optional<uint32_t> row = FieldIdToRow(field_id); + if (!row) + return; + WriteArg(key, storage_->GetArgValue(*row), writer); } - - void WriteValueForField(uint32_t field_id, SerializerValueWriter writer) { - WriteValueForField(field_id, [this, writer](const Variadic& variadic) { - (this->*writer)(variadic); - }); + void WriteArgAtRow(uint32_t arg_row, ValueWriter writer) { + const auto& args = storage_->arg_table(); + const auto& key = storage_->GetString(args.key()[arg_row]); + WriteArg(key, storage_->GetArgValue(arg_row), writer); } + void WriteArg(base::StringView key, Variadic value, ValueWriter writer); + // Value writing functions. void WriteValueForField(uint32_t field_id, ValueWriter writer) { - writer(storage_->GetArgValue(FieldIdToRow(field_id))); + base::Optional<uint32_t> row = FieldIdToRow(field_id); + if (!row) + return; + writer(storage_->GetArgValue(*row)); } - - void WriteArgAtRow(uint32_t arg_index) { - WriteArgAtRow(arg_index, - [this](const Variadic& v) { return WriteValue(v); }); - } - - void WriteArgAtRow(uint32_t arg_index, ValueWriter writer); - void WriteKernelFnValue(const Variadic& value) { if (value.type == Variadic::Type::kUint) { writer_->AppendHexInt(value.uint_value); @@ -113,21 +106,30 @@ class ArgsSerializer { PERFETTO_DFATAL("Invalid field type %d", static_cast<int>(value.type)); } } - void WriteValue(const Variadic& variadic); - uint32_t FieldIdToRow(uint32_t field_id) { + // The default value writer which uses the |WriteValue| function. + ValueWriter DVW() { return Wrap(&ArgsSerializer::WriteValue); } + ValueWriter Wrap(SerializerValueWriter writer) { + return [this, writer](const Variadic& v) { (this->*writer)(v); }; + } + + // Converts a field id to a row in the args table. + base::Optional<uint32_t> FieldIdToRow(uint32_t field_id) { PERFETTO_DCHECK(field_id > 0); PERFETTO_DCHECK(field_id < field_id_to_arg_index_->size()); - uint32_t index_in_arg_set = (*field_id_to_arg_index_)[field_id]; - return start_row_ + index_in_arg_set; + base::Optional<uint32_t> index_in_arg_set = + (*field_id_to_arg_index_)[field_id]; + return index_in_arg_set.has_value() + ? base::make_optional(start_row_ + *index_in_arg_set) + : base::nullopt; } const TraceStorage* storage_ = nullptr; TraceProcessorContext* context_ = nullptr; ArgSetId arg_set_id_ = kInvalidArgSetId; NullTermStringView event_name_; - std::vector<uint32_t>* field_id_to_arg_index_; + std::vector<base::Optional<uint32_t>>* field_id_to_arg_index_; RowMap row_map_; uint32_t start_row_ = 0; @@ -135,11 +137,12 @@ class ArgsSerializer { base::StringWriter* writer_ = nullptr; }; -ArgsSerializer::ArgsSerializer(TraceProcessorContext* context, - ArgSetId arg_set_id, - NullTermStringView event_name, - std::vector<uint32_t>* field_id_to_arg_index, - base::StringWriter* writer) +ArgsSerializer::ArgsSerializer( + TraceProcessorContext* context, + ArgSetId arg_set_id, + NullTermStringView event_name, + std::vector<base::Optional<uint32_t>>* field_id_to_arg_index, + base::StringWriter* writer) : context_(context), arg_set_id_(arg_set_id), event_name_(event_name), @@ -179,9 +182,9 @@ ArgsSerializer::ArgsSerializer(TraceProcessorContext* context, // Go through each field id and find the entry in the args table for that for (uint32_t i = 1; i <= max; ++i) { for (auto it = row_map_.IterateRows(); it; it.Next()) { - base::StringView key = args.key().GetString(it.row()); + base::StringView key = args.key().GetString(it.index()); if (key == descriptor->fields[i].name) { - (*field_id_to_arg_index)[i] = it.index(); + (*field_id_to_arg_index)[i] = it.row(); break; } } @@ -195,9 +198,9 @@ void ArgsSerializer::SerializeArgs() { if (event_name_ == "sched_switch") { using SS = protos::pbzero::SchedSwitchFtraceEvent; - WriteArgForField(SS::kPrevCommFieldNumber); - WriteArgForField(SS::kPrevPidFieldNumber); - WriteArgForField(SS::kPrevPrioFieldNumber); + WriteArgForField(SS::kPrevCommFieldNumber, DVW()); + WriteArgForField(SS::kPrevPidFieldNumber, DVW()); + WriteArgForField(SS::kPrevPrioFieldNumber, DVW()); WriteArgForField(SS::kPrevStateFieldNumber, [this](const Variadic& value) { PERFETTO_DCHECK(value.type == Variadic::Type::kInt); auto state = static_cast<uint16_t>(value.int_value); @@ -207,15 +210,15 @@ void ArgsSerializer::SerializeArgs() { ftrace_utils::TaskState(state, kernel_version).ToString('|').data()); }); writer_->AppendLiteral(" ==>"); - WriteArgForField(SS::kNextCommFieldNumber); - WriteArgForField(SS::kNextPidFieldNumber); - WriteArgForField(SS::kNextPrioFieldNumber); + WriteArgForField(SS::kNextCommFieldNumber, DVW()); + WriteArgForField(SS::kNextPidFieldNumber, DVW()); + WriteArgForField(SS::kNextPrioFieldNumber, DVW()); return; } else if (event_name_ == "sched_wakeup") { using SW = protos::pbzero::SchedWakeupFtraceEvent; - WriteArgForField(SW::kCommFieldNumber); - WriteArgForField(SW::kPidFieldNumber); - WriteArgForField(SW::kPrioFieldNumber); + WriteArgForField(SW::kCommFieldNumber, DVW()); + WriteArgForField(SW::kPidFieldNumber, DVW()); + WriteArgForField(SW::kPrioFieldNumber, DVW()); WriteArgForField(SW::kTargetCpuFieldNumber, [this](const Variadic& value) { PERFETTO_DCHECK(value.type == Variadic::Type::kInt); writer_->AppendPaddedInt<'0', 3>(value.int_value); @@ -224,28 +227,28 @@ void ArgsSerializer::SerializeArgs() { } else if (event_name_ == "clock_set_rate") { using CSR = protos::pbzero::ClockSetRateFtraceEvent; writer_->AppendLiteral(" "); - WriteValueForField(CSR::kNameFieldNumber); - WriteArgForField(CSR::kStateFieldNumber); - WriteArgForField(CSR::kCpuIdFieldNumber); + WriteValueForField(CSR::kNameFieldNumber, DVW()); + WriteArgForField(CSR::kStateFieldNumber, DVW()); + WriteArgForField(CSR::kCpuIdFieldNumber, DVW()); return; } else if (event_name_ == "clk_set_rate") { using CSR = protos::pbzero::ClkSetRateFtraceEvent; writer_->AppendLiteral(" "); - WriteValueForField(CSR::kNameFieldNumber); + WriteValueForField(CSR::kNameFieldNumber, DVW()); writer_->AppendLiteral(" "); - WriteValueForField(CSR::kRateFieldNumber); + WriteValueForField(CSR::kRateFieldNumber, DVW()); return; } else if (event_name_ == "clock_enable") { using CE = protos::pbzero::ClockEnableFtraceEvent; - WriteValueForField(CE::kNameFieldNumber); - WriteArgForField(CE::kStateFieldNumber); - WriteArgForField(CE::kCpuIdFieldNumber); + WriteValueForField(CE::kNameFieldNumber, DVW()); + WriteArgForField(CE::kStateFieldNumber, DVW()); + WriteArgForField(CE::kCpuIdFieldNumber, DVW()); return; } else if (event_name_ == "clock_disable") { using CD = protos::pbzero::ClockDisableFtraceEvent; - WriteValueForField(CD::kNameFieldNumber); - WriteArgForField(CD::kStateFieldNumber); - WriteArgForField(CD::kCpuIdFieldNumber); + WriteValueForField(CD::kNameFieldNumber, DVW()); + WriteArgForField(CD::kStateFieldNumber, DVW()); + WriteArgForField(CD::kCpuIdFieldNumber, DVW()); return; } else if (event_name_ == "binder_transaction") { using BT = protos::pbzero::BinderTransactionFtraceEvent; @@ -263,13 +266,13 @@ void ArgsSerializer::SerializeArgs() { }); writer_->AppendString(" dest_proc="); - WriteValueForField(BT::kToProcFieldNumber); + WriteValueForField(BT::kToProcFieldNumber, DVW()); writer_->AppendString(" dest_thread="); - WriteValueForField(BT::kToThreadFieldNumber); + WriteValueForField(BT::kToThreadFieldNumber, DVW()); writer_->AppendString(" reply="); - WriteValueForField(BT::kReplyFieldNumber); + WriteValueForField(BT::kReplyFieldNumber, DVW()); writer_->AppendString(" flags=0x"); WriteValueForField(BT::kFlagsFieldNumber, [this](const Variadic& value) { @@ -291,8 +294,8 @@ void ArgsSerializer::SerializeArgs() { PERFETTO_DCHECK(value.type == Variadic::Type::kInt); writer_->AppendUnsignedInt(static_cast<uint32_t>(value.int_value)); }); - WriteArgForField(BTAB::kDataSizeFieldNumber); - WriteArgForField(BTAB::kOffsetsSizeFieldNumber); + WriteArgForField(BTAB::kDataSizeFieldNumber, DVW()); + WriteArgForField(BTAB::kOffsetsSizeFieldNumber, DVW()); return; } else if (event_name_ == "binder_transaction_received") { using BTR = protos::pbzero::BinderTransactionReceivedFtraceEvent; @@ -321,7 +324,7 @@ void ArgsSerializer::SerializeArgs() { }); writer_->AppendString(" page=0000000000000000"); writer_->AppendString(" pfn="); - WriteValueForField(MFA::kPfnFieldNumber); + WriteValueForField(MFA::kPfnFieldNumber, DVW()); writer_->AppendString(" ofs="); WriteValueForField(MFA::kIndexFieldNumber, [this](const Variadic& value) { PERFETTO_DCHECK(value.type == Variadic::Type::kUint); @@ -345,10 +348,10 @@ void ArgsSerializer::SerializeArgs() { return; } else if (event_name_ == "sched_blocked_reason") { using SBR = protos::pbzero::SchedBlockedReasonFtraceEvent; - WriteArgForField(SBR::kPidFieldNumber); - WriteArgForField(SBR::kIoWaitFieldNumber); + WriteArgForField(SBR::kPidFieldNumber, DVW()); + WriteArgForField(SBR::kIoWaitFieldNumber, DVW()); WriteArgForField(SBR::kCallerFieldNumber, - &ArgsSerializer::WriteKernelFnValue); + Wrap(&ArgsSerializer::WriteKernelFnValue)); return; } else if (event_name_ == "workqueue_activate_work") { using WAW = protos::pbzero::WorkqueueActivateWorkFtraceEvent; @@ -367,7 +370,7 @@ void ArgsSerializer::SerializeArgs() { }); writer_->AppendString(": function "); WriteValueForField(WES::kFunctionFieldNumber, - &ArgsSerializer::WriteKernelFnValue); + Wrap(&ArgsSerializer::WriteKernelFnValue)); return; } else if (event_name_ == "workqueue_execute_end") { using WE = protos::pbzero::WorkqueueExecuteEndFtraceEvent; @@ -385,31 +388,31 @@ void ArgsSerializer::SerializeArgs() { writer_->AppendHexInt(value.uint_value); }); WriteArgForField(WQW::kFunctionFieldNumber, - &ArgsSerializer::WriteKernelFnValue); + Wrap(&ArgsSerializer::WriteKernelFnValue)); WriteArgForField(WQW::kWorkqueueFieldNumber, [this](const Variadic& value) { PERFETTO_DCHECK(value.type == Variadic::Type::kUint); writer_->AppendHexInt(value.uint_value); }); - WriteValueForField(WQW::kReqCpuFieldNumber); - WriteValueForField(WQW::kCpuFieldNumber); + WriteValueForField(WQW::kReqCpuFieldNumber, DVW()); + WriteValueForField(WQW::kCpuFieldNumber, DVW()); return; } else if (event_name_ == "irq_handler_entry") { using IEN = protos::pbzero::IrqHandlerEntryFtraceEvent; - WriteArgForField(IEN::kIrqFieldNumber); - WriteArgForField(IEN::kNameFieldNumber); + WriteArgForField(IEN::kIrqFieldNumber, DVW()); + WriteArgForField(IEN::kNameFieldNumber, DVW()); return; } else if (event_name_ == "irq_handler_exit") { using IEX = protos::pbzero::IrqHandlerExitFtraceEvent; - WriteArgForField(IEX::kIrqFieldNumber); + WriteArgForField(IEX::kIrqFieldNumber, DVW()); writer_->AppendString(" ret="); WriteValueForField(IEX::kRetFieldNumber, [this](const Variadic& value) { - PERFETTO_DCHECK(value.type == Variadic::Type::kUint); - writer_->AppendString(value.uint_value ? "handled" : "unhandled"); + PERFETTO_DCHECK(value.type == Variadic::Type::kInt); + writer_->AppendString(value.int_value ? "handled" : "unhandled"); }); return; } else if (event_name_ == "softirq_entry") { using SIE = protos::pbzero::SoftirqEntryFtraceEvent; - WriteArgForField(SIE::kVecFieldNumber); + WriteArgForField(SIE::kVecFieldNumber, DVW()); writer_->AppendString(" [action="); WriteValueForField(SIE::kVecFieldNumber, [this](const Variadic& value) { PERFETTO_DCHECK(value.type == Variadic::Type::kUint); @@ -419,7 +422,7 @@ void ArgsSerializer::SerializeArgs() { return; } else if (event_name_ == "softirq_exit") { using SIX = protos::pbzero::SoftirqExitFtraceEvent; - WriteArgForField(SIX::kVecFieldNumber); + WriteArgForField(SIX::kVecFieldNumber, DVW()); writer_->AppendString(" [action="); WriteValueForField(SIX::kVecFieldNumber, [this](const Variadic& value) { PERFETTO_DCHECK(value.type == Variadic::Type::kUint); @@ -434,11 +437,11 @@ void ArgsSerializer::SerializeArgs() { writer_->AppendChar(static_cast<char>(value.uint_value)); }); writer_->AppendString("|"); - WriteValueForField(TMW::kPidFieldNumber); + WriteValueForField(TMW::kPidFieldNumber, DVW()); writer_->AppendString("|"); - WriteValueForField(TMW::kNameFieldNumber); + WriteValueForField(TMW::kNameFieldNumber, DVW()); writer_->AppendString("|"); - WriteValueForField(TMW::kValueFieldNumber); + WriteValueForField(TMW::kValueFieldNumber, DVW()); return; } else if (event_name_ == "g2d_tracing_mark_write") { using TMW = protos::pbzero::G2dTracingMarkWriteFtraceEvent; @@ -447,25 +450,33 @@ void ArgsSerializer::SerializeArgs() { writer_->AppendChar(static_cast<char>(value.uint_value)); }); writer_->AppendString("|"); - WriteValueForField(TMW::kPidFieldNumber); + WriteValueForField(TMW::kPidFieldNumber, DVW()); writer_->AppendString("|"); - WriteValueForField(TMW::kNameFieldNumber); + WriteValueForField(TMW::kNameFieldNumber, DVW()); writer_->AppendString("|"); - WriteValueForField(TMW::kValueFieldNumber); + WriteValueForField(TMW::kValueFieldNumber, DVW()); + return; + } else if (event_name_ == "cgroup_attach_task") { + using CAT = protos::pbzero::CgroupAttachTaskFtraceEvent; + WriteArgForField(CAT::kDstRootFieldNumber, DVW()); + WriteArgForField(CAT::kDstIdFieldNumber, DVW()); + WriteArgForField(CAT::kCnameFieldNumber, "cgroup", DVW()); + WriteArgForField(CAT::kDstLevelFieldNumber, DVW()); + WriteArgForField(CAT::kDstPathFieldNumber, DVW()); + WriteArgForField(CAT::kPidFieldNumber, DVW()); + WriteArgForField(CAT::kCommFieldNumber, DVW()); return; } for (auto it = row_map_.IterateRows(); it; it.Next()) { - WriteArgAtRow(it.row()); + WriteArgAtRow(it.index(), DVW()); } } -void ArgsSerializer::WriteArgAtRow(uint32_t arg_row, ValueWriter writer) { - const auto& args = storage_->arg_table(); - const auto& key = storage_->GetString(args.key()[arg_row]); - auto value = storage_->GetArgValue(arg_row); - +void ArgsSerializer::WriteArg(base::StringView key, + Variadic value, + ValueWriter writer) { writer_->AppendChar(' '); - writer_->AppendString(key.c_str(), key.size()); + writer_->AppendString(key.data(), key.size()); writer_->AppendChar('='); if (key == "gfp_flags") { @@ -504,6 +515,9 @@ void ArgsSerializer::WriteValue(const Variadic& value) { writer_->AppendString(str.c_str(), str.size()); break; } + case Variadic::kNull: + writer_->AppendLiteral("[NULL]"); + break; } } @@ -543,7 +557,13 @@ void SqliteRawTable::ToSystrace(sqlite3_context* ctx, uint32_t row = static_cast<uint32_t>(sqlite3_value_int64(argv[0])); auto str = serializer_.SerializeToString(row); - sqlite3_result_text(ctx, str.release(), -1, free); + if (str.get() == nullptr) { + base::StackString<128> err("to_ftrace: Cannot serialize row id %u", row); + sqlite3_result_error(ctx, err.c_str(), -1); + return; + } + + sqlite3_result_text(ctx, str.release(), -1, str.get_deleter()); } SystraceSerializer::SystraceSerializer(TraceProcessorContext* context) @@ -558,10 +578,15 @@ SystraceSerializer::ScopedCString SystraceSerializer::SerializeToString( char line[4096]; base::StringWriter writer(line, sizeof(line)); - SerializePrefix(raw_row, &writer); - StringId event_name_id = raw.name()[raw_row]; NullTermStringView event_name = storage_->GetString(event_name_id); + if (event_name.StartsWith("chrome_event.") || + event_name.StartsWith("track_event.")) { + return ScopedCString(nullptr, nullptr); + } + + SerializePrefix(raw_row, &writer); + writer.AppendChar(' '); if (event_name == "print" || event_name == "g2d_tracing_mark_write" || event_name == "dpu_tracing_mark_write") { @@ -594,7 +619,7 @@ void SystraceSerializer::SerializePrefix(uint32_t raw_row, if (opt_upid.has_value()) { tgid = storage_->process_table().pid()[*opt_upid]; } - auto name = storage_->GetString(storage_->thread_table().name()[utid]); + auto name = storage_->thread_table().name().GetString(utid); FtraceTime ftrace_time(ts); if (tid == 0) { |