Support update name
diff --git a/src/trace_processor/importers/common/slice_tracker.cc b/src/trace_processor/importers/common/slice_tracker.cc
index f8608f2..4991e87 100644
--- a/src/trace_processor/importers/common/slice_tracker.cc
+++ b/src/trace_processor/importers/common/slice_tracker.cc
@@ -246,29 +246,54 @@
   if (!MaybeCloseStack(timestamp, kPendingDuration, stack, track_id)) {
     return std::nullopt;
   }
+
   if (stack.empty()) {
-    return std::nullopt;
-  }
-
-  auto* slices = context_->storage->mutable_slice_table();
-  std::optional<uint32_t> stack_idx = finder(stack);
-
-  if (!stack_idx) {
     return StartSlice(timestamp, kPendingDuration, track_id, args_callback,
                       std::move(inserter));
   }
 
-  const auto& slice_info = stack[stack_idx.value()];
+  auto* slices = context_->storage->mutable_slice_table();
 
-  tables::SliceTable::RowReference ref = slice_info.row.ToRowReference(slices);
-  PERFETTO_DCHECK(ref.dur() == kPendingDuration);
-
-  ArgsTracker& tracker = stack[stack_idx.value()].args_tracker;
-  if (args_callback) {
-    auto bound_inserter = tracker.AddArgsTo(ref.id());
-    args_callback(&bound_inserter);
+  std::optional<uint32_t> top_incomplete_idx;
+  for (int i = static_cast<int>(stack.size()) - 1; i >= 0; i--) {
+    auto ref = stack[static_cast<size_t>(i)].row.ToRowReference(slices);
+    if (ref.dur() == kPendingDuration) {
+      top_incomplete_idx = static_cast<uint32_t>(i);
+      break;
+    }
   }
-  return ref.id();
+
+  if (top_incomplete_idx) {
+    const auto& slice_info = stack[*top_incomplete_idx];
+    auto ref = slice_info.row.ToRowReference(slices);
+
+    std::optional<uint32_t> matching_idx = finder(stack);
+
+    if (matching_idx && *matching_idx == *top_incomplete_idx) {
+      // It matches and it is the top-most incomplete slice. Update it.
+      ArgsTracker& tracker = stack[*top_incomplete_idx].args_tracker;
+      if (args_callback) {
+        auto bound_inserter = tracker.AddArgsTo(ref.id());
+        args_callback(&bound_inserter);
+      }
+      return ref.id();
+    } else {
+      // It does not match the top-most incomplete slice.
+      // End the top-most incomplete slice.
+      ref.set_dur(timestamp - ref.ts());
+
+      if (*top_incomplete_idx == stack.size() - 1) {
+        StackPop(track_id);
+      }
+
+      return StartSlice(timestamp, kPendingDuration, track_id, args_callback,
+                        std::move(inserter));
+    }
+  } else {
+    // No incomplete slice on stack.
+    return StartSlice(timestamp, kPendingDuration, track_id, args_callback,
+                      std::move(inserter));
+  }
 }
 
 std::optional<SliceId> SliceTracker::CompleteSlice(
diff --git a/src/trace_processor/importers/common/slice_tracker_unittest.cc b/src/trace_processor/importers/common/slice_tracker_unittest.cc
index 538c610..4b3748f 100644
--- a/src/trace_processor/importers/common/slice_tracker_unittest.cc
+++ b/src/trace_processor/importers/common/slice_tracker_unittest.cc
@@ -223,6 +223,32 @@
   EXPECT_EQ(ar0.int_value(), 10);
 }
 
+TEST_F(SliceTrackerTest, UpdateNameMismatch) {
+  SliceTracker tracker(&context_);
+
+  constexpr TrackId track{22u};
+  tracker.Begin(2 /*ts*/, track, kNullStringId /*cat*/,
+                StringId::Raw(1) /*name*/);
+  tracker.Update(5 /*ts*/, track, kNullStringId /*cat*/,
+                 StringId::Raw(2) /*name*/);  // Different name
+  tracker.End(10 /*ts*/, track);
+
+  const auto& slices = context_.storage->slice_table();
+  EXPECT_EQ(slices.row_count(), 2u);
+
+  // First slice should be closed at ts=5
+  auto sr0 = slices[0];
+  EXPECT_EQ(sr0.ts(), 2);
+  EXPECT_EQ(sr0.dur(), 3);  // 5 - 2
+  EXPECT_EQ(sr0.name().value_or(kNullStringId).raw_id(), 1u);
+
+  // Second slice should start at ts=5 and be closed at ts=10
+  auto sr1 = slices[1];
+  EXPECT_EQ(sr1.ts(), 5);
+  EXPECT_EQ(sr1.dur(), 5);  // 10 - 5
+  EXPECT_EQ(sr1.name().value_or(kNullStringId).raw_id(), 2u);
+}
+
 TEST_F(SliceTrackerTest, OneSliceWithArgsWithTranslatedName) {
   SliceTracker tracker(&context_);