Skip to content

Commit

Permalink
Fixes #3678
Browse files Browse the repository at this point in the history
Refactor so that marks_with_checkpoints is just changed in one place, not arbitrarily access it. Ref counts had the same changes in a previous commit.

Fixes a bug for loaded persistent checkpoints where the re-created checkpoints did not get their reference counting correct.

This closes #3678
  • Loading branch information
theIDinside committed Jan 15, 2024
1 parent bc524da commit f1d5e90
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 15 deletions.
4 changes: 4 additions & 0 deletions src/GdbServer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2250,6 +2250,10 @@ Checkpoint::Checkpoint(ReplayTimeline& timeline, TaskUid last_continue_tuid,
mark = timeline.add_explicit_checkpoint();
} else {
mark = timeline.mark();
const auto prior = timeline.find_closest_mark_with_clone(mark);
if(prior) {
prior->get_internal()->inc_refcount();
}
}
}

Expand Down
29 changes: 14 additions & 15 deletions src/ReplayTimeline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ ReplayTimeline::Mark ReplayTimeline::mark() {
ReplayTimeline::Mark ReplayTimeline::recreate_mark_from_data(const MarkData& mark_data, ReplaySession::shr_ptr session) {
Mark result;
auto m = make_shared<InternalMark>(this, mark_data, session);

m->inc_refcount();
auto& mark_vector = marks[m->proto.key];
mark_vector.push_back(m);
result.ptr = mark_vector.back();
Expand All @@ -235,11 +235,7 @@ ReplayTimeline::Mark ReplayTimeline::recreate_mark_from_data(const MarkData& mar
void ReplayTimeline::register_mark_as_checkpoint(Mark& m) {
DEBUG_ASSERT(m.ptr && m.ptr->checkpoint && "Can't register mark as checkpoint if no checkpoint exists");
auto key = m.ptr->proto.key;
if (marks_with_checkpoints.find(key) == marks_with_checkpoints.end()) {
marks_with_checkpoints[key] = 1;
} else {
marks_with_checkpoints[key]++;
}
increase_mark_with_checkpoints(key);
m.ptr->inc_refcount();
}

Expand Down Expand Up @@ -313,6 +309,15 @@ ReplayTimeline::Mark ReplayTimeline::lazy_reverse_singlestep(const Mark& from,
return Mark();
}

void ReplayTimeline::increase_mark_with_checkpoints(
const MarkKey& key) noexcept {
if (marks_with_checkpoints.find(key) == marks_with_checkpoints.end()) {
marks_with_checkpoints[key] = 1;
} else {
marks_with_checkpoints[key]++;
}
}

ReplayTimeline::Mark ReplayTimeline::add_explicit_checkpoint() {
DEBUG_ASSERT(current->can_clone());

Expand All @@ -321,11 +326,7 @@ ReplayTimeline::Mark ReplayTimeline::add_explicit_checkpoint() {
unapply_breakpoints_and_watchpoints();
m.ptr->checkpoint = current->clone();
auto key = m.ptr->proto.key;
if (marks_with_checkpoints.find(key) == marks_with_checkpoints.end()) {
marks_with_checkpoints[key] = 1;
} else {
marks_with_checkpoints[key]++;
}
increase_mark_with_checkpoints(key);
}
m.ptr->inc_refcount();
return m;
Expand Down Expand Up @@ -798,11 +799,9 @@ ReplayTimeline::Mark ReplayTimeline::recreate_marks_for_non_explicit(const Check
// first add the mark with an actual clone, this is not a GDB checkpoint, but an RR checkpoint
auto mark = recreate_mark_from_data(cp.clone_data, clone);
reverse_exec_checkpoints[mark] = estimate_progress_of(*clone);
mark.get_internal()->inc_refcount();
register_mark_as_checkpoint(mark);
// then add the mark with no clone, the one that will be visible to GDB, i.e. non explicit checkpoint
Mark result = recreate_mark_from_data(*cp.non_explicit_mark_data, nullptr);
// auto internal = make_shared<InternalMark>(this, *cp.non_explicit_data, nullptr);
return result;
}

Expand Down Expand Up @@ -1736,8 +1735,8 @@ std::shared_ptr<ReplayTimeline::Mark> ReplayTimeline::find_closest_mark_with_clo
for(auto it = std::rbegin(marks_found->second); it != std::rend(marks_found->second); it++) {
DEBUG_ASSERT(it->get() != nullptr);
if((*it)->checkpoint) {
std::shared_ptr<Mark> result = std::make_shared<Mark>();
result->ptr = *it;
auto result = std::make_shared<Mark>();
result->ptr = *(it);
return result;
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/ReplayTimeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ class ReplayTimeline {
*/
void remove_explicit_checkpoint(const Mark& mark);

/** Find mark that has `key` and increase the checkpoint count for that mark. */
void increase_mark_with_checkpoints(const MarkKey& key) noexcept;

/**
* Return true if we're currently at the given mark.
*/
Expand Down

0 comments on commit f1d5e90

Please sign in to comment.