Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b85490f

Browse files
bbadawi1copybara-github
authored andcommitted
Fix iterator invalidation crash in TraceProcessor::ResolveFlows.
When processing large profile files, track.events vector can reallocate during push_back of instant events, invalidating iterators in the active loop and causing a SIGSEGV. This fix defers these push_backs until after the loop completes safely. PiperOrigin-RevId: 926390737
1 parent 4518436 commit b85490f

1 file changed

Lines changed: 20 additions & 1 deletion

File tree

xprof/convert/megascale_perfetto/trace_processor.cc

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,13 +413,19 @@ void TraceProcessor::ResolveFlows() {
413413
// Pass 1: Producers
414414
// ---------------------------------------------------------------------------
415415
// TPU Events: 'send' and 'recv'.
416+
int recv_done_counter = 0;
416417
visit_tpu_ops([&](int64_t tpu_id, Track& track, Event& event) {
418+
if (!absl::StartsWith(event.name, "send") &&
419+
!absl::StartsWith(event.name, "recv")) {
420+
return;
421+
}
417422
bool is_send;
418423
if (RE2::FullMatch(event.name, *kSendRe)) {
419424
is_send = true;
420425
} else if (RE2::FullMatch(event.name, *kRecvRe)) {
421426
is_send = false;
422427
} else {
428+
if (RE2::FullMatch(event.name, *kRecvDoneRe)) ++recv_done_counter;
423429
return; // Skip other events.
424430
}
425431

@@ -526,7 +532,16 @@ void TraceProcessor::ResolveFlows() {
526532
// ---------------------------------------------------------------------------
527533
// Pass 2: Consumers (send-done, recv-done)
528534
// ---------------------------------------------------------------------------
535+
// This pass may add a new instant event (recv-done END) for each recv-done.
536+
// We buffer these new events in this vector such that we can add them to
537+
// their respective tracks after we finish iterating through all tracks.
538+
std::vector<std::pair<Track*, Event>> pending_events;
539+
pending_events.reserve(recv_done_counter);
529540
visit_tpu_ops([&](int64_t tpu_id, Track& track, Event& event) {
541+
if (!absl::StartsWith(event.name, "send") &&
542+
!absl::StartsWith(event.name, "recv")) {
543+
return;
544+
}
530545
bool is_send_done;
531546
if (RE2::FullMatch(event.name, *kSendDoneRe)) {
532547
is_send_done = true;
@@ -581,9 +596,13 @@ void TraceProcessor::ResolveFlows() {
581596

582597
pop_flow(q_h2d_to_recv_done, key, instant_event);
583598

584-
track.events.push_back(std::move(instant_event));
599+
pending_events.push_back({&track, std::move(instant_event)});
585600
}
586601
});
602+
603+
for (auto& [track_ptr, event] : pending_events) {
604+
track_ptr->events.push_back(std::move(event));
605+
}
587606
}
588607

589608
void TraceProcessor::AddGlobalCounters() {

0 commit comments

Comments
 (0)