processor: Support RefType in SliceTracker + TrackEvent instant scopes
Adds support for tracking slice stacks for different RefTypes to
SliceTracker and uses this new support to implement handling of instant
event scopes from TrackEvent::LegacyEvent.
Bug: 130786981
Change-Id: I84205b63da0a489ed66b8f416c8bf96628076099
diff --git a/src/trace_processor/fuchsia_trace_parser.cc b/src/trace_processor/fuchsia_trace_parser.cc
index fa08d5b..4845e4d 100644
--- a/src/trace_processor/fuchsia_trace_parser.cc
+++ b/src/trace_processor/fuchsia_trace_parser.cc
@@ -206,7 +206,7 @@
UniqueTid utid =
procs->UpdateThread(static_cast<uint32_t>(tinfo.tid),
static_cast<uint32_t>(tinfo.pid));
- slices->Begin(ts, utid, cat, name);
+ slices->Begin(ts, utid, RefType::kRefUtid, cat, name);
break;
}
case kDurationEnd: {
@@ -216,7 +216,7 @@
// TODO(b/131181693): |cat| and |name| are not passed here so that
// if two slices end at the same timestep, the slices get closed in
// the correct order regardless of which end event is processed first.
- slices->End(ts, utid);
+ slices->End(ts, utid, RefType::kRefUtid);
break;
}
case kDurationComplete: {
@@ -225,7 +225,7 @@
UniqueTid utid =
procs->UpdateThread(static_cast<uint32_t>(tinfo.tid),
static_cast<uint32_t>(tinfo.pid));
- slices->Scoped(ts, utid, cat, name, end_ts - ts);
+ slices->Scoped(ts, utid, RefType::kRefUtid, cat, name, end_ts - ts);
break;
}
}
diff --git a/src/trace_processor/json_trace_parser.cc b/src/trace_processor/json_trace_parser.cc
index 8c1812e..4129bf1 100644
--- a/src/trace_processor/json_trace_parser.cc
+++ b/src/trace_processor/json_trace_parser.cc
@@ -90,11 +90,11 @@
switch (phase) {
case 'B': { // TRACE_EVENT_BEGIN.
- slice_tracker->Begin(timestamp, utid, cat_id, name_id);
+ slice_tracker->Begin(timestamp, utid, RefType::kRefUtid, cat_id, name_id);
break;
}
case 'E': { // TRACE_EVENT_END.
- slice_tracker->End(timestamp, utid, cat_id, name_id);
+ slice_tracker->End(timestamp, utid, RefType::kRefUtid, cat_id, name_id);
break;
}
case 'X': { // TRACE_EVENT (scoped event).
@@ -102,7 +102,8 @@
json_trace_utils::CoerceToNs(value["dur"]);
if (!opt_dur.has_value())
return;
- slice_tracker->Scoped(timestamp, utid, cat_id, name_id, opt_dur.value());
+ slice_tracker->Scoped(timestamp, utid, RefType::kRefUtid, cat_id, name_id,
+ opt_dur.value());
break;
}
case 'M': { // Metadata events (process and thread names).
diff --git a/src/trace_processor/proto_trace_parser.cc b/src/trace_processor/proto_trace_parser.cc
index b1c5a50..4849ffd 100644
--- a/src/trace_processor/proto_trace_parser.cc
+++ b/src/trace_processor/proto_trace_parser.cc
@@ -1451,30 +1451,54 @@
}
};
+ using LegacyEvent = protos::pbzero::TrackEvent::LegacyEvent;
+
int32_t phase = legacy_event.phase();
switch (static_cast<char>(phase)) {
case 'B': { // TRACE_EVENT_PHASE_BEGIN.
- slice_tracker->Begin(ts, utid, category_id, name_id, args_callback);
+ slice_tracker->Begin(ts, utid, RefType::kRefUtid, category_id, name_id,
+ args_callback);
break;
}
case 'E': { // TRACE_EVENT_PHASE_END.
- slice_tracker->End(ts, utid, category_id, name_id, args_callback);
+ slice_tracker->End(ts, utid, RefType::kRefUtid, category_id, name_id,
+ args_callback);
break;
}
case 'X': { // TRACE_EVENT_PHASE_COMPLETE.
auto duration_ns = legacy_event.duration_us() * 1000;
if (duration_ns < 0)
return;
- slice_tracker->Scoped(ts, utid, category_id, name_id, duration_ns,
- args_callback);
+ slice_tracker->Scoped(ts, utid, RefType::kRefUtid, category_id, name_id,
+ duration_ns, args_callback);
break;
}
+ case 'i':
case 'I': { // TRACE_EVENT_PHASE_INSTANT.
// Handle instant events as slices with zero duration, so that they end
// up nested underneath their parent slices.
int64_t duration_ns = 0;
- slice_tracker->Scoped(ts, utid, category_id, name_id, duration_ns,
- args_callback);
+
+ switch (legacy_event.instant_event_scope()) {
+ case LegacyEvent::SCOPE_UNSPECIFIED:
+ case LegacyEvent::SCOPE_THREAD:
+ slice_tracker->Scoped(ts, utid, RefType::kRefUtid, category_id,
+ name_id, duration_ns, args_callback);
+ break;
+ case LegacyEvent::SCOPE_GLOBAL:
+ slice_tracker->Scoped(ts, /*ref=*/0, RefType::kRefNoRef, category_id,
+ name_id, duration_ns, args_callback);
+ break;
+ case LegacyEvent::SCOPE_PROCESS:
+ slice_tracker->Scoped(ts, procs->GetOrCreateProcess(pid),
+ RefType::kRefUpid, category_id, name_id,
+ duration_ns, args_callback);
+ break;
+ default:
+ PERFETTO_FATAL("Unknown instant event scope: %u",
+ legacy_event.instant_event_scope());
+ break;
+ }
break;
}
case 'M': { // TRACE_EVENT_PHASE_METADATA (process and thread names).
@@ -1742,8 +1766,8 @@
sprintf(fallback, "Event %d", eid);
name_id = context_->storage->InternString(fallback);
}
- context_->slice_tracker->Scoped(ts, utid, cat_id, name_id,
- event.event_duration_ns());
+ context_->slice_tracker->Scoped(ts, utid, RefType::kRefUtid, cat_id,
+ name_id, event.event_duration_ns());
} else if (event.has_counter_id()) {
auto cid = event.counter_id();
if (cid < metatrace::COUNTERS_MAX) {
diff --git a/src/trace_processor/proto_trace_parser_unittest.cc b/src/trace_processor/proto_trace_parser_unittest.cc
index 020219b..4f605f2 100644
--- a/src/trace_processor/proto_trace_parser_unittest.cc
+++ b/src/trace_processor/proto_trace_parser_unittest.cc
@@ -106,6 +106,8 @@
base::StringView process_name));
MOCK_METHOD2(UpdateThread, UniqueTid(uint32_t tid, uint32_t tgid));
+
+ MOCK_METHOD1(GetOrCreateProcess, UniquePid(uint32_t pid));
};
class MockTraceStorage : public TraceStorage {
@@ -131,21 +133,24 @@
public:
MockSliceTracker(TraceProcessorContext* context) : SliceTracker(context) {}
- MOCK_METHOD5(Begin,
+ MOCK_METHOD6(Begin,
void(int64_t timestamp,
- UniqueTid utid,
+ int64_t ref,
+ RefType ref_type,
StringId cat,
StringId name,
SetArgsCallback args_callback));
- MOCK_METHOD5(End,
+ MOCK_METHOD6(End,
void(int64_t timestamp,
- UniqueTid utid,
+ int64_t ref,
+ RefType ref_type,
StringId cat,
StringId name,
SetArgsCallback args_callback));
- MOCK_METHOD6(Scoped,
+ MOCK_METHOD7(Scoped,
void(int64_t timestamp,
- UniqueTid utid,
+ int64_t ref,
+ RefType ref_type,
StringId cat,
StringId name,
int64_t duration,
@@ -609,9 +614,9 @@
.WillRepeatedly(Return(1));
InSequence in_sequence; // Below slices should be sorted by timestamp.
- EXPECT_CALL(*slice_, Scoped(1005000, 1, 0, 0, 23000, _));
- EXPECT_CALL(*slice_, Begin(1010000, 1, 0, 0, _));
- EXPECT_CALL(*slice_, End(1020000, 1, 0, 0, _));
+ EXPECT_CALL(*slice_, Scoped(1005000, 1, RefType::kRefUtid, 0, 0, 23000, _));
+ EXPECT_CALL(*slice_, Begin(1010000, 1, RefType::kRefUtid, 0, 0, _));
+ EXPECT_CALL(*slice_, End(1020000, 1, RefType::kRefUtid, 0, 0, _));
context_.sorter->ExtractEventsForced();
}
@@ -665,6 +670,18 @@
auto* packet = trace_.add_packet();
packet->set_trusted_packet_sequence_id(1);
auto* event = packet->set_track_event();
+ event->set_timestamp_absolute_us(1050);
+ event->add_category_iids(1);
+ auto* legacy_event = event->set_legacy_event();
+ legacy_event->set_name_iid(1);
+ legacy_event->set_phase('i');
+ legacy_event->set_instant_event_scope(
+ protos::pbzero::TrackEvent::LegacyEvent::SCOPE_PROCESS);
+ }
+ {
+ auto* packet = trace_.add_packet();
+ packet->set_trusted_packet_sequence_id(1);
+ auto* event = packet->set_track_event();
event->set_timestamp_delta_us(10); // absolute: 1020.
event->set_thread_time_delta_us(5); // absolute: 2010.
event->add_category_iids(1);
@@ -701,26 +718,30 @@
Tokenize();
EXPECT_CALL(*process_, UpdateThread(16, 15))
- .Times(4)
+ .Times(5)
.WillRepeatedly(Return(1));
+ EXPECT_CALL(*process_, GetOrCreateProcess(15)).WillOnce(Return(2));
+
InSequence in_sequence; // Below slices should be sorted by timestamp.
EXPECT_CALL(*storage_, InternString(base::StringView("cat2,cat3")))
.WillOnce(Return(1));
EXPECT_CALL(*storage_, InternString(base::StringView("ev2")))
.WillOnce(Return(2));
- EXPECT_CALL(*slice_, Scoped(1005000, 1, 1, 2, 23000, _));
+ EXPECT_CALL(*slice_, Scoped(1005000, 1, RefType::kRefUtid, 1, 2, 23000, _));
EXPECT_CALL(*storage_, InternString(base::StringView("cat1")))
.WillOnce(Return(3));
EXPECT_CALL(*storage_, InternString(base::StringView("ev1")))
.WillOnce(Return(4));
- EXPECT_CALL(*slice_, Begin(1010000, 1, 3, 4, _));
+ EXPECT_CALL(*slice_, Begin(1010000, 1, RefType::kRefUtid, 3, 4, _));
- EXPECT_CALL(*slice_, End(1020000, 1, 3, 4, _));
+ EXPECT_CALL(*slice_, End(1020000, 1, RefType::kRefUtid, 3, 4, _));
- EXPECT_CALL(*slice_, Scoped(1040000, 1, 3, 4, 0, _));
+ EXPECT_CALL(*slice_, Scoped(1040000, 1, RefType::kRefUtid, 3, 4, 0, _));
+
+ EXPECT_CALL(*slice_, Scoped(1050000, 2, RefType::kRefUpid, 3, 4, 0, _));
context_.sorter->ExtractEventsForced();
}
@@ -754,7 +775,7 @@
Tokenize();
- EXPECT_CALL(*slice_, Begin(_, _, _, _, _)).Times(0);
+ EXPECT_CALL(*slice_, Begin(_, _, _, _, _, _)).Times(0);
context_.sorter->ExtractEventsForced();
}
@@ -779,7 +800,7 @@
Tokenize();
- EXPECT_CALL(*slice_, Begin(_, _, _, _, _)).Times(0);
+ EXPECT_CALL(*slice_, Begin(_, _, _, _, _, _)).Times(0);
context_.sorter->ExtractEventsForced();
}
@@ -875,8 +896,8 @@
.WillRepeatedly(Return(1));
InSequence in_sequence; // Below slices should be sorted by timestamp.
- EXPECT_CALL(*slice_, Begin(1010000, 1, 0, 0, _));
- EXPECT_CALL(*slice_, End(2010000, 1, 0, 0, _));
+ EXPECT_CALL(*slice_, Begin(1010000, 1, RefType::kRefUtid, 0, 0, _));
+ EXPECT_CALL(*slice_, End(2010000, 1, RefType::kRefUtid, 0, 0, _));
context_.sorter->ExtractEventsForced();
}
@@ -983,16 +1004,16 @@
EXPECT_CALL(*storage_, InternString(base::StringView("ev2")))
.WillOnce(Return(2));
- EXPECT_CALL(*slice_, Begin(1005000, 2, 1, 2, _));
+ EXPECT_CALL(*slice_, Begin(1005000, 2, RefType::kRefUtid, 1, 2, _));
EXPECT_CALL(*storage_, InternString(base::StringView("cat1")))
.WillOnce(Return(1));
EXPECT_CALL(*storage_, InternString(base::StringView("ev1")))
.WillOnce(Return(3));
- EXPECT_CALL(*slice_, Begin(1010000, 1, 1, 3, _));
- EXPECT_CALL(*slice_, End(1015000, 2, 1, 2, _));
- EXPECT_CALL(*slice_, End(1020000, 1, 1, 3, _));
+ EXPECT_CALL(*slice_, Begin(1010000, 1, RefType::kRefUtid, 1, 3, _));
+ EXPECT_CALL(*slice_, End(1015000, 2, RefType::kRefUtid, 1, 2, _));
+ EXPECT_CALL(*slice_, End(1020000, 1, RefType::kRefUtid, 1, 3, _));
context_.sorter->ExtractEventsForced();
}
@@ -1128,8 +1149,8 @@
.WillOnce(Return(1));
EXPECT_CALL(*storage_, InternString(base::StringView("ev1")))
.WillOnce(Return(2));
- EXPECT_CALL(*slice_, Begin(1010000, 1, 1, 2, _))
- .WillOnce(testing::InvokeArgument<4>(&args, 1u));
+ EXPECT_CALL(*slice_, Begin(1010000, 1, RefType::kRefUtid, 1, 2, _))
+ .WillOnce(testing::InvokeArgument<5>(&args, 1u));
EXPECT_CALL(*storage_, InternString(base::StringView("debug.an1")))
.WillOnce(Return(3));
EXPECT_CALL(args, AddArg(1u, 3, 3, Variadic::UnsignedInteger(10u)));
@@ -1162,8 +1183,8 @@
.WillOnce(Return(10));
EXPECT_CALL(args, AddArg(1u, 6, 10, Variadic::Integer(23)));
- EXPECT_CALL(*slice_, End(1020000, 1, 1, 2, _))
- .WillOnce(testing::InvokeArgument<4>(&args, 1u));
+ EXPECT_CALL(*slice_, End(1020000, 1, RefType::kRefUtid, 1, 2, _))
+ .WillOnce(testing::InvokeArgument<5>(&args, 1u));
EXPECT_CALL(*storage_, InternString(base::StringView("debug.an3")))
.WillOnce(Return(11));
@@ -1243,8 +1264,8 @@
.WillOnce(Return(1));
EXPECT_CALL(*storage_, InternString(base::StringView("ev1")))
.WillOnce(Return(2));
- EXPECT_CALL(*slice_, Begin(1010000, 1, 1, 2, _))
- .WillOnce(testing::InvokeArgument<4>(&args, 1u));
+ EXPECT_CALL(*slice_, Begin(1010000, 1, RefType::kRefUtid, 1, 2, _))
+ .WillOnce(testing::InvokeArgument<5>(&args, 1u));
EXPECT_CALL(*storage_, InternString(base::StringView("file1")))
.WillOnce(Return(3));
EXPECT_CALL(*storage_, InternString(base::StringView("func1")))
diff --git a/src/trace_processor/slice_tracker.cc b/src/trace_processor/slice_tracker.cc
index 281b279..1f51f11 100644
--- a/src/trace_processor/slice_tracker.cc
+++ b/src/trace_processor/slice_tracker.cc
@@ -45,11 +45,12 @@
UniqueTid utid =
context_->process_tracker->UpdateThread(ftrace_tid, atrace_tgid);
ftrace_to_atrace_tgid_[ftrace_tid] = atrace_tgid;
- Begin(timestamp, utid, cat, name);
+ Begin(timestamp, utid, RefType::kRefUtid, cat, name);
}
void SliceTracker::Begin(int64_t timestamp,
- UniqueTid utid,
+ int64_t ref,
+ RefType ref_type,
StringId cat,
StringId name,
SetArgsCallback args_callback) {
@@ -60,12 +61,14 @@
}
prev_timestamp_ = timestamp;
- MaybeCloseStack(timestamp, &threads_[utid]);
- StartSlice(timestamp, kPendingDuration, utid, cat, name, args_callback);
+ MaybeCloseStack(timestamp, &stacks_[std::make_pair(ref, ref_type)]);
+ StartSlice(timestamp, kPendingDuration, ref, ref_type, cat, name,
+ args_callback);
}
void SliceTracker::Scoped(int64_t timestamp,
- UniqueTid utid,
+ int64_t ref,
+ RefType ref_type,
StringId cat,
StringId name,
int64_t duration,
@@ -78,17 +81,18 @@
prev_timestamp_ = timestamp;
PERFETTO_DCHECK(duration >= 0);
- MaybeCloseStack(timestamp, &threads_[utid]);
- StartSlice(timestamp, duration, utid, cat, name, args_callback);
+ MaybeCloseStack(timestamp, &stacks_[std::make_pair(ref, ref_type)]);
+ StartSlice(timestamp, duration, ref, ref_type, cat, name, args_callback);
}
void SliceTracker::StartSlice(int64_t timestamp,
int64_t duration,
- UniqueTid utid,
+ int64_t ref,
+ RefType ref_type,
StringId cat,
StringId name,
SetArgsCallback args_callback) {
- auto* stack = &threads_[utid];
+ auto* stack = &stacks_[std::make_pair(ref, ref_type)];
auto* slices = context_->storage->mutable_nestable_slices();
const uint8_t depth = static_cast<uint8_t>(stack->size());
@@ -98,9 +102,8 @@
}
int64_t parent_stack_id =
depth == 0 ? 0 : slices->stack_ids()[stack->back().first];
- uint32_t slice_idx =
- slices->AddSlice(timestamp, duration, utid, RefType::kRefUtid, cat, name,
- depth, 0, parent_stack_id);
+ uint32_t slice_idx = slices->AddSlice(timestamp, duration, ref, ref_type, cat,
+ name, depth, 0, parent_stack_id);
stack->emplace_back(std::make_pair(slice_idx, ArgsTracker(context_)));
if (args_callback) {
@@ -131,11 +134,12 @@
}
UniqueTid utid =
context_->process_tracker->UpdateThread(ftrace_tid, actual_tgid);
- End(timestamp, utid);
+ End(timestamp, utid, RefType::kRefUtid);
}
void SliceTracker::End(int64_t timestamp,
- UniqueTid utid,
+ int64_t ref,
+ RefType ref_type,
StringId cat,
StringId name,
SetArgsCallback args_callback) {
@@ -146,9 +150,10 @@
}
prev_timestamp_ = timestamp;
- MaybeCloseStack(timestamp, &threads_[utid]);
+ auto ref_and_type = std::make_pair(ref, ref_type);
+ MaybeCloseStack(timestamp, &stacks_[ref_and_type]);
- auto& stack = threads_[utid];
+ auto& stack = stacks_[ref_and_type];
if (stack.empty())
return;
@@ -171,12 +176,12 @@
TraceStorage::CreateRowId(TableId::kNestableSlices, slice_idx));
}
- CompleteSlice(utid);
+ CompleteSlice(ref_and_type);
// TODO(primiano): auto-close B slices left open at the end.
}
-void SliceTracker::CompleteSlice(UniqueTid utid) {
- threads_[utid].pop_back();
+void SliceTracker::CompleteSlice(StackMapKey ref_and_type) {
+ stacks_[ref_and_type].pop_back();
}
void SliceTracker::MaybeCloseStack(int64_t ts, SlicesStack* stack) {
diff --git a/src/trace_processor/slice_tracker.h b/src/trace_processor/slice_tracker.h
index 58c3f2b..9354c51 100644
--- a/src/trace_processor/slice_tracker.h
+++ b/src/trace_processor/slice_tracker.h
@@ -42,14 +42,16 @@
// virtual for testing
virtual void Begin(int64_t timestamp,
- UniqueTid utid,
+ int64_t ref,
+ RefType ref_type,
StringId cat,
StringId name,
SetArgsCallback args_callback = SetArgsCallback());
// virtual for testing
virtual void Scoped(int64_t timestamp,
- UniqueTid utid,
+ int64_t ref,
+ RefType ref_type,
StringId cat,
StringId name,
int64_t duration,
@@ -59,7 +61,8 @@
// virtual for testing
virtual void End(int64_t timestamp,
- UniqueTid utid,
+ int64_t ref,
+ RefType ref_type,
StringId opt_cat = {},
StringId opt_name = {},
SetArgsCallback args_callback = SetArgsCallback());
@@ -67,13 +70,25 @@
private:
using SlicesStack = std::vector<std::pair<uint32_t /* row */, ArgsTracker>>;
+ using StackMapKey = std::pair<int64_t, RefType>;
+ struct StackMapHash {
+ size_t operator()(const StackMapKey& p) const {
+ base::Hash hash;
+ hash.Update(p.first);
+ hash.Update(p.second);
+ return static_cast<size_t>(hash.digest());
+ }
+ };
+ using StackMap = std::unordered_map<StackMapKey, SlicesStack, StackMapHash>;
+
void StartSlice(int64_t timestamp,
int64_t duration,
- UniqueTid utid,
+ int64_t ref,
+ RefType ref_type,
StringId cat,
StringId name,
SetArgsCallback args_callback);
- void CompleteSlice(UniqueTid tid);
+ void CompleteSlice(StackMapKey ref_and_type);
void MaybeCloseStack(int64_t end_ts, SlicesStack*);
int64_t GetStackHash(const SlicesStack&);
@@ -83,7 +98,7 @@
int64_t prev_timestamp_ = 0;
TraceProcessorContext* const context_;
- std::unordered_map<UniqueTid, SlicesStack> threads_;
+ StackMap stacks_;
std::unordered_map<uint32_t, uint32_t> ftrace_to_atrace_tgid_;
};
diff --git a/src/trace_processor/slice_tracker_unittest.cc b/src/trace_processor/slice_tracker_unittest.cc
index 88b1e1d..78a32ee 100644
--- a/src/trace_processor/slice_tracker_unittest.cc
+++ b/src/trace_processor/slice_tracker_unittest.cc
@@ -57,8 +57,8 @@
context.storage.reset(new TraceStorage());
SliceTracker tracker(&context);
- tracker.Begin(2 /*ts*/, 42 /*tid*/, 0 /*cat*/, 1 /*name*/);
- tracker.End(10 /*ts*/, 42 /*tid*/, 0 /*cat*/, 1 /*name*/);
+ tracker.Begin(2 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0 /*cat*/, 1 /*name*/);
+ tracker.End(10 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0 /*cat*/, 1 /*name*/);
auto slices = context.storage->nestable_slices();
EXPECT_EQ(slices.slice_count(), 1u);
@@ -77,12 +77,12 @@
context.storage.reset(new TraceStorage());
SliceTracker tracker(&context);
- tracker.Begin(2 /*ts*/, 42 /*tid*/, 0 /*cat*/, 1 /*name*/,
+ tracker.Begin(2 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0 /*cat*/, 1 /*name*/,
[](ArgsTracker* args_tracker, RowId row) {
args_tracker->AddArg(row, /*flat_key=*/1, /*key=*/2,
/*value=*/Variadic::Integer(10));
});
- tracker.End(10 /*ts*/, 42 /*tid*/, 0 /*cat*/, 1 /*name*/,
+ tracker.End(10 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0 /*cat*/, 1 /*name*/,
[](ArgsTracker* args_tracker, RowId row) {
args_tracker->AddArg(row, /*flat_key=*/3, /*key=*/4,
/*value=*/Variadic::Integer(20));
@@ -115,10 +115,10 @@
context.storage.reset(new TraceStorage());
SliceTracker tracker(&context);
- tracker.Begin(2 /*ts*/, 42 /*tid*/, 0 /*cat*/, 1 /*name*/);
- tracker.Begin(3 /*ts*/, 42 /*tid*/, 0 /*cat*/, 2 /*name*/);
- tracker.End(5 /*ts*/, 42 /*tid*/);
- tracker.End(10 /*ts*/, 42 /*tid*/);
+ tracker.Begin(2 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0 /*cat*/, 1 /*name*/);
+ tracker.Begin(3 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0 /*cat*/, 2 /*name*/);
+ tracker.End(5 /*ts*/, 42 /*ref*/, RefType::kRefUtid);
+ tracker.End(10 /*ts*/, 42 /*ref*/, RefType::kRefUtid);
auto slices = context.storage->nestable_slices();
@@ -151,11 +151,11 @@
context.storage.reset(new TraceStorage());
SliceTracker tracker(&context);
- tracker.Begin(0 /*ts*/, 42 /*tid*/, 0, 0);
- tracker.Begin(1 /*ts*/, 42 /*tid*/, 0, 0);
- tracker.Scoped(2 /*ts*/, 42 /*tid*/, 0, 0, 6);
- tracker.End(9 /*ts*/, 42 /*tid*/);
- tracker.End(10 /*ts*/, 42 /*tid*/);
+ tracker.Begin(0 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0, 0);
+ tracker.Begin(1 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0, 0);
+ tracker.Scoped(2 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0, 0, 6);
+ tracker.End(9 /*ts*/, 42 /*ref*/, RefType::kRefUtid);
+ tracker.End(10 /*ts*/, 42 /*ref*/, RefType::kRefUtid);
auto slices = ToSliceInfo(context.storage->nestable_slices());
EXPECT_THAT(slices,
@@ -167,10 +167,10 @@
context.storage.reset(new TraceStorage());
SliceTracker tracker(&context);
- tracker.Begin(2 /*ts*/, 42 /*tid*/, 0 /*cat*/, 1 /*name*/);
- tracker.End(3 /*ts*/, 42 /*tid*/, 1 /*cat*/, 1 /*name*/);
- tracker.End(4 /*ts*/, 42 /*tid*/, 0 /*cat*/, 2 /*name*/);
- tracker.End(5 /*ts*/, 42 /*tid*/, 0 /*cat*/, 1 /*name*/);
+ tracker.Begin(2 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0 /*cat*/, 1 /*name*/);
+ tracker.End(3 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 1 /*cat*/, 1 /*name*/);
+ tracker.End(4 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0 /*cat*/, 2 /*name*/);
+ tracker.End(5 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0 /*cat*/, 1 /*name*/);
auto slices = ToSliceInfo(context.storage->nestable_slices());
EXPECT_THAT(slices, ElementsAre(SliceInfo{2, 3}));
@@ -184,16 +184,38 @@
// Bug scenario: the second zero-length scoped slice prevents the first slice
// from being closed, leading to an inconsistency when we try to insert the
// final slice and it doesn't intersect with the still pending first slice.
- tracker.Scoped(2 /*ts*/, 42 /*tid*/, 0 /*cat*/, 1 /*name*/, 10 /* dur */);
- tracker.Scoped(2 /*ts*/, 42 /*tid*/, 0 /*cat*/, 1 /*name*/, 0 /* dur */);
- tracker.Scoped(12 /*ts*/, 42 /*tid*/, 0 /*cat*/, 1 /*name*/, 1 /* dur */);
- tracker.Scoped(13 /*ts*/, 42 /*tid*/, 0 /*cat*/, 1 /*name*/, 1 /* dur */);
+ tracker.Scoped(2 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0 /*cat*/, 1 /*name*/,
+ 10 /* dur */);
+ tracker.Scoped(2 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0 /*cat*/, 1 /*name*/,
+ 0 /* dur */);
+ tracker.Scoped(12 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0 /*cat*/,
+ 1 /*name*/, 1 /* dur */);
+ tracker.Scoped(13 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0 /*cat*/,
+ 1 /*name*/, 1 /* dur */);
auto slices = ToSliceInfo(context.storage->nestable_slices());
EXPECT_THAT(slices, ElementsAre(SliceInfo{2, 10}, SliceInfo{2, 0},
SliceInfo{12, 1}, SliceInfo{13, 1}));
}
+TEST(SliceTrackerTest, DifferentRefTypes) {
+ TraceProcessorContext context;
+ context.storage.reset(new TraceStorage());
+ SliceTracker tracker(&context);
+
+ tracker.Begin(0 /*ts*/, 42 /*ref*/, RefType::kRefUtid, 0, 0);
+ tracker.Scoped(2 /*ts*/, 42 /*ref*/, RefType::kRefUpid, 0, 0, 6);
+ tracker.End(10 /*ts*/, 42 /*ref*/, RefType::kRefUtid);
+
+ auto slices = ToSliceInfo(context.storage->nestable_slices());
+ EXPECT_THAT(slices, ElementsAre(SliceInfo{0, 10}, SliceInfo{2, 6}));
+
+ EXPECT_EQ(context.storage->nestable_slices().types()[0], RefType::kRefUtid);
+ EXPECT_EQ(context.storage->nestable_slices().types()[1], RefType::kRefUpid);
+ EXPECT_EQ(context.storage->nestable_slices().depths()[0], 0);
+ EXPECT_EQ(context.storage->nestable_slices().depths()[1], 0);
+}
+
} // namespace
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/syscall_tracker.h b/src/trace_processor/syscall_tracker.h
index d2c910f..b797395 100644
--- a/src/trace_processor/syscall_tracker.h
+++ b/src/trace_processor/syscall_tracker.h
@@ -49,14 +49,18 @@
void Enter(int64_t ts, UniqueTid utid, uint32_t syscall_num) {
StringId name = SyscallNumberToStringId(syscall_num);
- if (name)
- context_->slice_tracker->Begin(ts, utid, 0 /* cat */, name);
+ if (name) {
+ context_->slice_tracker->Begin(ts, utid, RefType::kRefUtid, 0 /* cat */,
+ name);
+ }
}
void Exit(int64_t ts, UniqueTid utid, uint32_t syscall_num) {
StringId name = SyscallNumberToStringId(syscall_num);
- if (name)
- context_->slice_tracker->End(ts, utid, 0 /* cat */, name);
+ if (name) {
+ context_->slice_tracker->End(ts, utid, RefType::kRefUtid, 0 /* cat */,
+ name);
+ }
}
private:
diff --git a/src/trace_processor/syscall_tracker_unittest.cc b/src/trace_processor/syscall_tracker_unittest.cc
index 716889a..a5a5318 100644
--- a/src/trace_processor/syscall_tracker_unittest.cc
+++ b/src/trace_processor/syscall_tracker_unittest.cc
@@ -33,15 +33,17 @@
MockSliceTracker(TraceProcessorContext* context) : SliceTracker(context) {}
virtual ~MockSliceTracker() = default;
- MOCK_METHOD5(Begin,
+ MOCK_METHOD6(Begin,
void(int64_t timestamp,
- UniqueTid utid,
+ int64_t ref,
+ RefType ref_type,
StringId cat,
StringId name,
SetArgsCallback args_callback));
- MOCK_METHOD5(End,
+ MOCK_METHOD6(End,
void(int64_t timestamp,
- UniqueTid utid,
+ int64_t ref,
+ RefType ref_type,
StringId cat,
StringId name,
SetArgsCallback args_callback));
@@ -64,10 +66,10 @@
TEST_F(SyscallTrackerTest, ReportUnknownSyscalls) {
StringId begin_name = 0;
StringId end_name = 0;
- EXPECT_CALL(*slice_tracker, Begin(100, 42, 0, _, _))
- .WillOnce(SaveArg<3>(&begin_name));
- EXPECT_CALL(*slice_tracker, End(110, 42, 0, _, _))
- .WillOnce(SaveArg<3>(&end_name));
+ EXPECT_CALL(*slice_tracker, Begin(100, 42, RefType::kRefUtid, 0, _, _))
+ .WillOnce(SaveArg<4>(&begin_name));
+ EXPECT_CALL(*slice_tracker, End(110, 42, RefType::kRefUtid, 0, _, _))
+ .WillOnce(SaveArg<4>(&end_name));
context.syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 57 /*sys_read*/);
context.syscall_tracker->Exit(110 /*ts*/, 42 /*utid*/, 57 /*sys_read*/);
@@ -77,8 +79,8 @@
TEST_F(SyscallTrackerTest, IgnoreWriteSyscalls) {
context.syscall_tracker->SetArchitecture(kAarch64);
- EXPECT_CALL(*slice_tracker, Begin(_, _, _, _, _)).Times(0);
- EXPECT_CALL(*slice_tracker, End(_, _, _, _, _)).Times(0);
+ EXPECT_CALL(*slice_tracker, Begin(_, _, _, _, _, _)).Times(0);
+ EXPECT_CALL(*slice_tracker, End(_, _, _, _, _, _)).Times(0);
context.syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 64 /*sys_write*/);
context.syscall_tracker->Exit(110 /*ts*/, 42 /*utid*/, 64 /*sys_write*/);
@@ -87,10 +89,10 @@
TEST_F(SyscallTrackerTest, Aarch64) {
StringId begin_name = 0;
StringId end_name = 0;
- EXPECT_CALL(*slice_tracker, Begin(100, 42, 0, _, _))
- .WillOnce(SaveArg<3>(&begin_name));
- EXPECT_CALL(*slice_tracker, End(110, 42, 0, _, _))
- .WillOnce(SaveArg<3>(&end_name));
+ EXPECT_CALL(*slice_tracker, Begin(100, 42, RefType::kRefUtid, 0, _, _))
+ .WillOnce(SaveArg<4>(&begin_name));
+ EXPECT_CALL(*slice_tracker, End(110, 42, RefType::kRefUtid, 0, _, _))
+ .WillOnce(SaveArg<4>(&end_name));
context.syscall_tracker->SetArchitecture(kAarch64);
context.syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 63 /*sys_read*/);
@@ -102,10 +104,10 @@
TEST_F(SyscallTrackerTest, x8664) {
StringId begin_name = 0;
StringId end_name = 0;
- EXPECT_CALL(*slice_tracker, Begin(100, 42, 0, _, _))
- .WillOnce(SaveArg<3>(&begin_name));
- EXPECT_CALL(*slice_tracker, End(110, 42, 0, _, _))
- .WillOnce(SaveArg<3>(&end_name));
+ EXPECT_CALL(*slice_tracker, Begin(100, 42, RefType::kRefUtid, 0, _, _))
+ .WillOnce(SaveArg<4>(&begin_name));
+ EXPECT_CALL(*slice_tracker, End(110, 42, RefType::kRefUtid, 0, _, _))
+ .WillOnce(SaveArg<4>(&end_name));
context.syscall_tracker->SetArchitecture(kX86_64);
context.syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 0 /*sys_read*/);
@@ -115,8 +117,8 @@
}
TEST_F(SyscallTrackerTest, SyscallNumberTooLarge) {
- EXPECT_CALL(*slice_tracker, Begin(_, _, _, _, _)).Times(0);
- EXPECT_CALL(*slice_tracker, End(_, _, _, _, _)).Times(0);
+ EXPECT_CALL(*slice_tracker, Begin(_, _, _, _, _, _)).Times(0);
+ EXPECT_CALL(*slice_tracker, End(_, _, _, _, _, _)).Times(0);
context.syscall_tracker->SetArchitecture(kAarch64);
context.syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 9999);
context.syscall_tracker->Exit(110 /*ts*/, 42 /*utid*/, 9999);